[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
RE: Debugging threaded processes
With some help from David Holland, I have a tentative fix. Tentative,
because the program is segfaulting at some point; I don't know yet why,
or whether to blame that on the program, on GDB, or on NetBSD.
Anyway, the underlying problem is that p_xstat is used for two purposes
when debugging a process:
1. When stopping due to a signal (like breakpoint), it contains signo
which will be sent to GDB.
2. When GDB tells the process to continue, it contains the signo to be
delivered to the process at that time.
The precise problem in the multi-threaded case is that runnable LWPs for
the process are stopped one at a time as they pass through userret. So
when the thread that hit the break is stopped and switches away, another
thread of the same process may run next.
If that other thread had previously switched also, it will resume in
sigswitch after the mi_switch call, which means it calls sigchecktrace
to see if GDB continued it with a signal. Unfortunately, we're in case
(1) not in case (2), so p_xtrace contains the signo due to the
breakpoint trap that still needs to be delivered to GDB.
Solution: for case (1), PS_STOPPING is set in p_sflag and for case (2)
it is not. So have sigchecktrace test PS_STOPPING and return 0 instead
of what's in p_xtrace if it is.
The patch looks like this:
--- sys/kern/kern_sig.c.orig 2010-03-18 12:25:46.000000000 -0400
+++ sys/kern/kern_sig.c 2010-03-18 13:44:12.000000000 -0400
@@ -1674,9 +1674,10 @@
* If we are no longer being traced, or the parent didn't
- * give us a signal, look for more signals.
+ * give us a signal, or we're stopping, look for more signals.
- if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xstat == 0)
+ if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xstat == 0 ||
+ (p->p_sflag & PS_STOPPING) != 0)
(This is against the 5.0.1 sources, if it makes a difference)
Main Index |
Thread Index |