diff --git a/gdb-bz471819-lwp-dead.patch b/gdb-bz471819-lwp-dead.patch new file mode 100644 index 0000000..c5ecb4e --- /dev/null +++ b/gdb-bz471819-lwp-dead.patch @@ -0,0 +1,204 @@ +gdb/ +2009-06-27 Jan Kratochvil + + * linux-nat.c (num_lwps): Do not count DEAD LWPs. + (delete_lwp): Only set LP as DEAD if it is INFERIOR_PTID. + (iterate_over_lwps): Skip DEAD LPs. Discard DEAD LPs not in + INFERIOR_PTID. + (linux_nat_resume): Do not resume DEAD LPs. Extend the debug message. + * linux-nat.h (struct lwp_info): New field `dead'. + +gdb/testsuite/ +2009-06-27 Jan Kratochvil + + * gdb.threads/current-lwp-dead.exp, gdb.threads/current-lwp-dead.c: New. + +--- gdb-6.8.50.20090302/gdb/linux-nat.c.orig 2009-06-29 10:56:39.000000000 +0200 ++++ gdb-6.8.50.20090302/gdb/linux-nat.c 2009-06-29 11:01:25.000000000 +0200 +@@ -1192,7 +1192,15 @@ delete_lwp (ptid_t ptid) + if (!lp) + return; + +- num_lwps--; ++ if (!lp->dead) ++ num_lwps--; ++ ++ if (ptid_equal (ptid, inferior_ptid)) ++ { ++ /* Delay the deletion the same way as in delete_thread_1. */ ++ lp->dead = 1; ++ return; ++ } + + if (lpprev) + lpprev->next = lp->next; +@@ -1236,6 +1244,16 @@ iterate_over_lwps (int (*callback) (stru + for (lp = lwp_list; lp; lp = lpnext) + { + lpnext = lp->next; ++ ++ /* Ignored already dead LWPs. Moreover delete them if we no longer have ++ to keep them around. */ ++ if (lp->dead) ++ { ++ if (!ptid_equal (lp->ptid, inferior_ptid)) ++ delete_lwp (lp->ptid); ++ continue; ++ } ++ + if ((*callback) (lp, data)) + return lp; + } +@@ -1943,15 +1961,19 @@ linux_nat_resume (struct target_ops *ops + if (resume_all) + iterate_over_lwps (resume_callback, NULL); + +- linux_ops->to_resume (linux_ops, ptid, step, signo); +- memset (&lp->siginfo, 0, sizeof (lp->siginfo)); ++ if (!lp->dead) ++ { ++ linux_ops->to_resume (linux_ops, ptid, step, signo); ++ memset (&lp->siginfo, 0, sizeof (lp->siginfo)); ++ } + + if (debug_linux_nat) + fprintf_unfiltered (gdb_stdlog, +- "LLR: %s %s, %s (resume event thread)\n", ++ "LLR: %s %s, %s, %s (resume event thread)\n", + step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT", + target_pid_to_str (ptid), +- signo ? strsignal (signo) : "0"); ++ signo ? strsignal (signo) : "0", ++ lp->dead ? "dead" : "alive"); + + if (target_can_async_p ()) + target_async (inferior_event_handler, 0); +--- a/gdb/linux-nat.h ++++ b/gdb/linux-nat.h +@@ -32,6 +32,12 @@ struct lwp_info + and overall process id. */ + ptid_t ptid; + ++ /* If this flag is set, the lwp is known to be dead already (exit ++ event already received in a my_waitpid()). Such LWP should not longer be ++ iterated and it is being kept only temporarily if it is still referenced ++ by INFERIOR_PTID. */ ++ int dead; ++ + /* Non-zero if this LWP is cloned. In this context "cloned" means + that the LWP is reporting to its parent using a signal other than + SIGCHLD. */ +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/current-lwp-dead.c +@@ -0,0 +1,75 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2009 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 . ++ ++ Do not use threads as we need to exploit a bug in LWP code masked by the ++ threads code otherwise. ++ ++ INFERIOR_PTID must point to exited LWP. Here we use the initial LWP as it ++ is automatically INFERIOR_PTID for GDB. ++ ++ Finally we need to call target_resume (RESUME_ALL, ...) which we invoke by ++ NEW_THREAD_EVENT (called from the new LWP as initial LWP is exited now). */ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++ ++#define STACK_SIZE 0x1000 ++ ++static int ++fn_abort (void *unused) ++{ ++ return 0; /* at-fn_abort */ ++} ++ ++static int ++fn (void *unused) ++{ ++ int i; ++ unsigned char *stack; ++ int new_pid; ++ ++ i = sleep (1); ++ assert (i == 0); ++ ++ stack = malloc (STACK_SIZE); ++ assert (stack != NULL); ++ ++ new_pid = clone (fn_abort, stack + STACK_SIZE, CLONE_FILES | CLONE_VM, NULL, ++ NULL, NULL, NULL); ++ assert (new_pid > 0); ++ ++ return 0; ++} ++ ++int ++main (int argc, char **argv) ++{ ++ unsigned char *stack; ++ int new_pid; ++ ++ stack = malloc (STACK_SIZE); ++ assert (stack != NULL); ++ ++ new_pid = clone (fn, stack + STACK_SIZE, CLONE_FILES | CLONE_VM, NULL, NULL, ++ NULL, NULL); ++ assert (new_pid > 0); ++ ++ return 0; ++} +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.threads/current-lwp-dead.exp +@@ -0,0 +1,31 @@ ++# This testcase is part of GDB, the GNU debugger. ++ ++# Copyright 2009 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 . ++ ++# Please email any bugs, comments, and/or additions to this file to: ++# bug-gdb@gnu.org ++ ++if { [prepare_for_testing current-lwp-dead.exp current-lwp-dead] } { ++ return -1 ++} ++ ++if {[runto_main] <= 0} { ++ untested current-lwp-dead.exp ++ return -1 ++} ++ ++gdb_breakpoint "fn_abort" ++gdb_continue_to_breakpoint "fn_abort" ".*at-fn_abort.*" diff --git a/gdb.spec b/gdb.spec index c921462..72a1d11 100644 --- a/gdb.spec +++ b/gdb.spec @@ -15,7 +15,7 @@ Version: 6.8.50.20090302 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 35%{?_with_upstream:.upstream}%{?dist} +Release: 36%{?_with_upstream:.upstream}%{?dist} License: GPLv3+ Group: Development/Debuggers @@ -393,6 +393,9 @@ Patch373: gdb-DW_OP_call_frame_cfa.patch # Accelerate sorting blocks on reading a file (found on WebKit) (BZ 507267). patch374: gdb-bz507267-block-sort-fast.patch +# Fix GDB crash on cloned-TIDs with no associated pthread (BZ 471819). +patch375: gdb-bz471819-lwp-dead.patch + BuildRequires: ncurses-devel texinfo gettext flex bison expat-devel Requires: readline BuildRequires: readline-devel @@ -595,6 +598,7 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch370 -p1 %patch373 -p1 %patch374 -p1 +%patch375 -p1 %patch124 -p1 find -name "*.orig" | xargs rm -f @@ -668,7 +672,7 @@ CFLAGS="$CFLAGS -O0 -ggdb2" %else --without-python \ %endif - --with-rpm=librpm.so \ + --with-rpm=librpm.so.0 \ %ifarch ia64 --with-libunwind \ %else @@ -895,6 +899,10 @@ fi %endif %changelog +* Mon Jun 29 2009 Jan Kratochvil - 6.8.50.20090302-36 +- Fix GDB crash on cloned-TIDs with no associated pthread (BZ 471819). +- Workaround rpm.org#76 rpm-devel requirement for debuginfo names (BZ 508193). + * Mon Jun 22 2009 Jan Kratochvil - 6.8.50.20090302-35 - Accelerate sorting blocks on reading a file (found on WebKit) (BZ 507267).