aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2010-08-28 14:51:29 +0000
committerPedro Alves <palves@redhat.com>2010-08-28 14:51:29 +0000
commit1a98136022a77a76368172186234580a9decbdd8 (patch)
tree64acaa0699410daa98de3b49f5599f4fd91c3c2f
parentb4d51a55f99ed33da4f4d061c18d0e4fca63a29b (diff)
downloadgdb-1a98136022a77a76368172186234580a9decbdd8.zip
gdb-1a98136022a77a76368172186234580a9decbdd8.tar.gz
gdb-1a98136022a77a76368172186234580a9decbdd8.tar.bz2
* linux-low.c (__SIGRTMIN): Define if not already defined.
(linux_create_inferior): Check for __ANDROID__ rather than __SIGRTMIN. (enqueue_one_deferred_signal): Don't requeue non-RT signals that are already deferred. (linux_wait_1): Check for __ANDROID__ rather than __SIGRTMIN. (linux_resume_one_thread): Don't queue a SIGSTOP if the lwp is stopped and already has a pending signal to report. (proceed_one_lwp): : Don't queue a SIGSTOP if the lwp already has a pending signal to report or is moving out of a jump pad. (linux_init_signals): Check for __ANDROID__ rather than __SIGRTMIN.
-rw-r--r--gdb/gdbserver/ChangeLog15
-rw-r--r--gdb/gdbserver/linux-low.c49
2 files changed, 59 insertions, 5 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index fc7bb90..65e6b78 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,5 +1,20 @@
2010-08-28 Pedro Alves <pedro@codesourcery.com>
+ * linux-low.c (__SIGRTMIN): Define if not already defined.
+ (linux_create_inferior): Check for __ANDROID__ rather than
+ __SIGRTMIN.
+ (enqueue_one_deferred_signal): Don't requeue non-RT signals that
+ are already deferred.
+ (linux_wait_1): Check for __ANDROID__ rather than __SIGRTMIN.
+ (linux_resume_one_thread): Don't queue a SIGSTOP if the lwp is
+ stopped and already has a pending signal to report.
+ (proceed_one_lwp): : Don't queue a SIGSTOP if the lwp already has
+ a pending signal to report or is moving out of a jump pad.
+ (linux_init_signals): Check for __ANDROID__ rather than
+ __SIGRTMIN.
+
+2010-08-28 Pedro Alves <pedro@codesourcery.com>
+
* linux-low.c (linux_stabilize_threads): Wrap debug output in a
debug_threads check. Avoid a linear search when not doing debug
output.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index cbcb840..714dac3 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -98,6 +98,12 @@
#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
#endif
+/* This is the kernel's hard limit. Not to be confused with
+ SIGRTMIN. */
+#ifndef __SIGRTMIN
+#define __SIGRTMIN 32
+#endif
+
#ifdef __UCLIBC__
#if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__))
#define HAS_NOMMU
@@ -566,7 +572,7 @@ linux_create_inferior (char *program, char **allargs)
{
ptrace (PTRACE_TRACEME, 0, 0, 0);
-#ifdef __SIGRTMIN /* Bionic doesn't use SIGRTMIN the way glibc does. */
+#ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does. */
signal (__SIGRTMIN + 1, SIG_DFL);
#endif
@@ -1337,6 +1343,30 @@ Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
fprintf (stderr, " (no more currently queued signals)\n");
}
+ /* Don't enqueue non-RT signals if they are already in the deferred
+ queue. (SIGSTOP being the easiest signal to see ending up here
+ twice) */
+ if (WSTOPSIG (*wstat) < __SIGRTMIN)
+ {
+ struct pending_signals *sig;
+
+ for (sig = lwp->pending_signals_to_report;
+ sig != NULL;
+ sig = sig->prev)
+ {
+ if (sig->signal == WSTOPSIG (*wstat))
+ {
+ if (debug_threads)
+ fprintf (stderr,
+ "Not requeuing already queued non-RT signal %d"
+ " for LWP %ld\n",
+ sig->signal,
+ lwpid_of (lwp));
+ return;
+ }
+ }
+ }
+
p_sig = xmalloc (sizeof (*p_sig));
p_sig->prev = lwp->pending_signals_to_report;
p_sig->signal = WSTOPSIG (*wstat);
@@ -2230,7 +2260,7 @@ Check if we're already there.\n",
if (WIFSTOPPED (w)
&& current_inferior->last_resume_kind != resume_step
&& (
-#if defined (USE_THREAD_DB) && defined (__SIGRTMIN)
+#if defined (USE_THREAD_DB) && !defined (__ANDROID__)
(current_process ()->private->thread_db != NULL
&& (WSTOPSIG (w) == __SIGRTMIN
|| WSTOPSIG (w) == __SIGRTMIN + 1))
@@ -3332,7 +3362,14 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
the thread already has a pending status to report, we
will still report it the next time we wait - see
status_pending_p_callback. */
- send_sigstop (lwp);
+
+ /* If we already have a pending signal to report, then
+ there's no need to queue a SIGSTOP, as this means we're
+ midway through moving the LWP out of the jumppad, and we
+ will report the pending signal as soon as that is
+ finished. */
+ if (lwp->pending_signals_to_report == NULL)
+ send_sigstop (lwp);
}
/* For stop requests, we're done. */
@@ -3500,7 +3537,9 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
return 0;
}
- if (thread->last_resume_kind == resume_stop)
+ if (thread->last_resume_kind == resume_stop
+ && lwp->pending_signals_to_report == NULL
+ && lwp->collecting_fast_tracepoint == 0)
{
/* We haven't reported this LWP as stopped yet (otherwise, the
last_status.kind check above would catch it, and we wouldn't
@@ -5117,7 +5156,7 @@ linux_init_signals ()
{
/* FIXME drow/2002-06-09: As above, we should check with LinuxThreads
to find what the cancel signal actually is. */
-#ifdef __SIGRTMIN /* Bionic doesn't use SIGRTMIN the way glibc does. */
+#ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does. */
signal (__SIGRTMIN+1, SIG_IGN);
#endif
}