PR gdb/18717: internal error if non-leader thread exits process

If a non-leader thread exits the process while all other threads are
ptrace-stopped, native gdb fails an assertion.  The test added by this
commit catches it:

 /home/pedro/gdb/mygit/build/../src/gdb/linux-nat.c:3198: internal-error: linux_nat_filter_event: Assertion `lp->resumed' failed.
 A problem internal to GDB has been detected,
 further debugging may prove unreliable.
 Quit this debugging session? (y or n)
 FAIL: gdb.threads/non-leader-exit-process.exp: program exits normally (GDB internal error)

The fix is just to remove the assertion.

With that out of the way, neither GDB not GDBserver handle this
perfectly though, so I'm adding a KFAIL:

 (gdb) continue
 Continuing.
 [Thread 0x7ffff7fc0700 (LWP 15350) exited]
 No unwaited-for children left.
 Couldn't get registers: No such process.
 (gdb) KFAIL: gdb.threads/non-ldr-exit.exp: program exits normally (PRMS: gdb/18717)

gdb/ChangeLog:
2015-07-24  Pedro Alves  <palves@redhat.com>

	PR gdb/18717
	* linux-nat.c (linux_nat_filter_event): Don't assert that the lwp
	is resumed, and extend the debug log.

gdb/testsuite/ChangeLog:
2015-07-24  Pedro Alves  <palves@redhat.com>

	PR gdb/18717
	* gdb.threads/non-ldr-exit.c: New file.
	* gdb.threads/non-ldr-exit.exp: New file.
This commit is contained in:
Pedro Alves 2015-07-24 18:18:44 +00:00
parent fe23c31f26
commit 7759842763
5 changed files with 104 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2015-07-24 Pedro Alves <palves@redhat.com>
PR gdb/18717
* linux-nat.c (linux_nat_filter_event): Don't assert that the lwp
is resumed, and extend the debug log.
2015-07-24 Pedro Alves <palves@redhat.com>
* fork-child.c (fork_inferior): Print argv[0] instead of exec_file.

View File

@ -3195,12 +3195,14 @@ linux_nat_filter_event (int lwpid, int status)
}
}
gdb_assert (lp->resumed);
/* Note that even if the leader was ptrace-stopped, it can still
exit, if e.g., some other thread brings down the whole
process (calls `exit'). So don't assert that the lwp is
resumed. */
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"Process %ld exited\n",
ptid_get_lwp (lp->ptid));
"Process %ld exited (resumed=%d)\n",
ptid_get_lwp (lp->ptid), lp->resumed);
/* This was the last lwp in the process. Since events are
serialized to GDB core, we may not be able report this one

View File

@ -1,3 +1,9 @@
2015-07-24 Pedro Alves <palves@redhat.com>
PR gdb/18717
* gdb.threads/non-ldr-exit.c: New file.
* gdb.threads/non-ldr-exit.exp: New file.
2015-07-24 Yao Qi <yao.qi@linaro.org>
* gdb.server/ext-wrapper.exp: Test --wrapper option when

View File

@ -0,0 +1,41 @@
/* Clean exit of the thread group leader should not break GDB.
Copyright 2015 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
static void *
start (void *arg)
{
exit (0); /* break-here */
return arg;
}
int
main (void)
{
pthread_t thread;
int i;
i = pthread_create (&thread, NULL, start, NULL);
assert (i == 0);
i = pthread_join (thread, NULL);
abort ();
return 0;
}

View File

@ -0,0 +1,45 @@
# Copyright (C) 2015 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Exit of the thread group leader should not break GDB.
standard_testfile
set executable ${testfile}
if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] == -1} {
return -1
}
if ![runto_main] {
fail "Can't run to main"
return -1
}
gdb_breakpoint [gdb_get_line_number "break-here"]
gdb_continue_to_breakpoint "break-here" ".* break-here .*"
# Now lock all threads but the one that calls exit.
gdb_test_no_output "set scheduler-locking on"
set test "program exits normally"
gdb_test_multiple "continue" $test {
-re "exited normally.*$gdb_prompt " {
pass $test
}
-re "No unwaited-for children left.*$gdb_prompt " {
setup_kfail "gdb/18717" "*-*-linux*"
fail $test
}
}