This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] lin-lwp.c change to avoid obscure hanging
- From: "Paul N. Hilfinger" <hilfingr at otisco dot mckusick dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Sat, 13 Apr 2002 02:05:28 -0700
- Subject: [RFA] lin-lwp.c change to avoid obscure hanging
- References: <200204121931.g3CJVae12068@reddwarf.sfbay.redhat.com>
- Reply-to: Hilfinger at otisco dot mckusick dot com
Under certain obscure conditions, GDB will hang when continuing a program
that uses GNU/Linux LWPs. For example, one set of circumstances that
were uncovered in an Ada program were:
1. A breakpoint is tripped over in thread A.
2. When all threads are stopped, it turns out that thread B != A has received
a signal (specifically SIG32, which is apparently used by the thread
package). This signal, furthermore, is "not of interest" to GDB
(as if according to 'set handle SIG32 pass noprint nostop').
A and B here stand for integer literals, of course.
3. The user executes the commands
delete
thread B
continue
I am uncertain as to the proper fix is for this, but I have provided
one possibility below (that works for us). The long ugly comment
will, I hope, prompt the more experienced among you to resolve the
outstanding questions.
Paul Hilfinger
ACT, Inc.
2002-04-10 Paul N. Hilfinger <hilfingr@otisco.mckusick.com>
* lin-lwp.c (lin_lwp_resume): Pass unprocessed signals to the
selected lwp, if GDB is not interested in them, and no specific
signal is requested. Fixes regression (hanging) displayed by
9820-005__task_switch.
Index: gdb/lin-lwp.c
===================================================================
RCS file: /cvs/src/src/gdb/lin-lwp.c,v
retrieving revision 1.34
diff -u -p -r1.34 lin-lwp.c
--- gdb/lin-lwp.c 31 Mar 2002 15:10:38 -0000 1.34
+++ gdb/lin-lwp.c 13 Apr 2002 08:41:20 -0000
@@ -605,6 +605,32 @@ lin_lwp_resume (ptid_t ptid, int step, e
/* Mark this LWP as resumed. */
lp->resumed = 1;
+ if (WIFSTOPPED (lp->status))
+ {
+ enum target_signal stopsig
+ = target_signal_from_host (WSTOPSIG (lp->status));
+
+ /* If we have a signal GDB is not interested in, then
+ arrange to pass it to the process without comment. This
+ should be able to happen only when one changes threads
+ before continuing. To be conservative, we do this only
+ if signo is TARGET_SIGNAL_0.
+ FIXME: hilfinger/2002-04-10: But this means we can't
+ switch to this thread and clear its signal. We could try
+ simply not resuming when lp->status is non-zero, and
+ leave it to lin_lwp_wait to catch the unhandled signal,
+ but it will resume ONLY this thread (see Kettenis's FIXME
+ in lin_lwp_wait), and this is not always right. */
+
+ if (signo == TARGET_SIGNAL_0
+ && signal_stop_state (stopsig) == 0
+ && signal_print_state (stopsig) == 0
+ && signal_pass_state (stopsig) == 1)
+ {
+ signo = stopsig;
+ lp->status = 0;
+ }
+ }
/* If we have a pending wait status for this thread, there is no
point in resuming the process. */
if (lp->status)