aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-07-22 18:01:46 +0100
committerPedro Alves <palves@redhat.com>2015-07-30 18:52:09 +0100
commit69dde7dcb81f6baf2b823dcc03e040c29ee5de7d (patch)
tree4b5f202f1fc74eb80385a3ce1a85dc9007f26937 /gdb
parent4dd63d488a76482543517c4c4cde699ee6fa33ef (diff)
downloadgdb-69dde7dcb81f6baf2b823dcc03e040c29ee5de7d.zip
gdb-69dde7dcb81f6baf2b823dcc03e040c29ee5de7d.tar.gz
gdb-69dde7dcb81f6baf2b823dcc03e040c29ee5de7d.tar.bz2
PR threads/18600: Inferiors left around after fork+thread spawn
The new gdb.threads/fork-plus-threads.exp test exposes one more problem. When one types "info inferiors" after running the program, one see's a couple inferior left still, while there should only be inferior #1 left. E.g.: (gdb) info inferiors Num Description Executable 4 process 8393 /home/pedro/bugs/src/test 2 process 8388 /home/pedro/bugs/src/test * 1 <null> /home/pedro/bugs/src/test (gdb) info threads Calling prune_inferiors() manually at this point (from a top gdb) does not remove them, because they still have inf->pid != 0 (while they shouldn't). This suggests that we never mourned those inferiors. Enabling logs (master + previous patch) we see: ... WL: waitpid Thread 0x7ffff7fc2740 (LWP 9513) received Trace/breakpoint trap (stopped) WL: Handling extended status 0x03057f LHEW: Got clone event from LWP 9513, new child is LWP 9579 [New Thread 0x7ffff37b8700 (LWP 9579)] WL: waitpid Thread 0x7ffff7fc2740 (LWP 9508) received 0 (exited) WL: Thread 0x7ffff7fc2740 (LWP 9508) exited. ^^^^^^^^ [Thread 0x7ffff7fc2740 (LWP 9508) exited] WL: waitpid Thread 0x7ffff7fc2740 (LWP 9499) received 0 (exited) WL: Thread 0x7ffff7fc2740 (LWP 9499) exited. [Thread 0x7ffff7fc2740 (LWP 9499) exited] RSRL: resuming stopped-resumed LWP Thread 0x7ffff37b8700 (LWP 9579) at 0x3615ef4ce1: step=0 ... (gdb) info inferiors Num Description Executable 5 process 9508 /home/pedro/bugs/src/test ^^^^ 4 process 9503 /home/pedro/bugs/src/test 3 process 9500 /home/pedro/bugs/src/test 2 process 9499 /home/pedro/bugs/src/test * 1 <null> /home/pedro/bugs/src/test (gdb) ... Note the "Thread 0x7ffff7fc2740 (LWP 9508) exited." line. That's this in wait_lwp: /* Check if the thread has exited. */ if (WIFEXITED (status) || WIFSIGNALED (status)) { thread_dead = 1; if (debug_linux_nat) fprintf_unfiltered (gdb_stdlog, "WL: %s exited.\n", target_pid_to_str (lp->ptid)); } } That was the leader thread reporting an exit, meaning the whole process is gone. So the problem is that this code doesn't understand that an WIFEXITED status of the leader LWP should be reported to infrun as process exit. gdb/ChangeLog: 2015-07-30 Pedro Alves <palves@redhat.com> PR threads/18600 * linux-nat.c (wait_lwp): Report to the core when thread group leader exits. gdb/testsuite/ChangeLog: 2015-07-30 Pedro Alves <palves@redhat.com> PR threads/18600 * gdb.threads/fork-plus-threads.exp: Test that "info inferiors" only shows inferior 1.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/linux-nat.c14
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.threads/fork-plus-threads.exp4
4 files changed, 30 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 40403f9..64fbe8e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,10 @@
2015-07-30 Pedro Alves <palves@redhat.com>
+
+ PR threads/18600
+ * linux-nat.c (wait_lwp): Report to the core when thread group
+ leader exits.
+
+2015-07-30 Pedro Alves <palves@redhat.com>
Simon Marchi <simon.marchi@ericsson.com>
PR threads/18600
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 966c6a8..69cfefc 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2274,6 +2274,20 @@ wait_lwp (struct lwp_info *lp)
/* Check if the thread has exited. */
if (WIFEXITED (status) || WIFSIGNALED (status))
{
+ if (ptid_get_pid (lp->ptid) == ptid_get_lwp (lp->ptid))
+ {
+ if (debug_linux_nat)
+ fprintf_unfiltered (gdb_stdlog, "WL: Process %d exited.\n",
+ ptid_get_pid (lp->ptid));
+
+ /* This is the leader exiting, it means the whole
+ process is gone. Store the status to report to the
+ core. Store it in lp->waitstatus, because lp->status
+ would be ambiguous (W_EXITCODE(0,0) == 0). */
+ store_waitstatus (&lp->waitstatus, status);
+ return 0;
+ }
+
thread_dead = 1;
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog, "WL: %s exited.\n",
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 06ca987..e3126ed 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-07-30 Pedro Alves <palves@redhat.com>
+
+ PR threads/18600
+ * gdb.threads/fork-plus-threads.exp: Test that "info inferiors"
+ only shows inferior 1.
+
2015-07-30 Simon Marchi <simon.marchi@ericsson.com>
Pedro Alves <palves@redhat.com>
diff --git a/gdb/testsuite/gdb.threads/fork-plus-threads.exp b/gdb/testsuite/gdb.threads/fork-plus-threads.exp
index 53d1102..8a503ec 100644
--- a/gdb/testsuite/gdb.threads/fork-plus-threads.exp
+++ b/gdb/testsuite/gdb.threads/fork-plus-threads.exp
@@ -60,6 +60,10 @@ proc do_test { detach_on_fork } {
gdb_test "info threads" "No threads\." \
"no threads left"
+
+ gdb_test "info inferiors" \
+ "Num\[ \t\]+Description\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \
+ "only inferior 1 left"
}
foreach detach_on_fork {"on" "off"} {