diff --git a/gdb-6.5-attach-stop.patch b/gdb-6.5-attach-stop.patch index bce0b4c..69dbd55 100644 --- a/gdb-6.5-attach-stop.patch +++ b/gdb-6.5-attach-stop.patch @@ -1,41 +1,57 @@ -sleep 1h& pid=$!; kill -STOP $pid; gdb sleep $pid - -> -Attaching to program: /bin/sleep, process 20768 -../../gdb/linux-nat.c:1057: internal-error: linux_nat_attach: Assertion `pid == GET_PID (inferior_ptid) && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP' failed. +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=209521 +https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=219118 +http://sources.redhat.com/ml/gdb-patches/2006-09/msg00092.html Specific to Red Hat kernels, kernel.org kernels lockup on gdb "attach". -2006-09-17 Jan Kratochvil +2006-12-11 Jan Kratochvil * gdb-6.5/gdb/linux-nat.c (linux_nat_attach): Handle already stopped - processes. + processes, compiled either in a nonthreaded or a threaded mode. -2006-09-17 Jeff Johnston +2006-12-11 Jeff Johnston Jan Kratochvil * gdb.base/attachstop.exp, gdb.base/attachstop.c: New files, - test attaching to already stopped processes. + test attaching to already stopped processes, compiled either in + a nonthreaded or a threaded mode. -Index: gdb-6.5/gdb/linux-nat.c -=================================================================== -RCS file: /cvs/src/src/gdb/linux-nat.c,v -retrieving revision 1.50 -diff -u -p -r1.50 linux-nat.c ---- gdb-6.5-orig/gdb/linux-nat.c 16 Sep 2006 09:48:12 -0000 1.50 -+++ gdb-6.5/gdb/linux-nat.c 17 Sep 2006 21:50:32 -0000 -@@ -1022,13 +1022,16 @@ linux_nat_attach (char *args, int from_t +diff -u -ruNp gdb-6.5-orig/gdb/linux-nat.c gdb-6.5/gdb/linux-nat.c +--- gdb-6.5-orig/gdb/linux-nat.c 2006-12-12 00:30:18.000000000 +0100 ++++ gdb-6.5/gdb/linux-nat.c 2006-12-11 23:42:23.000000000 +0100 +@@ -567,7 +567,9 @@ linux_handle_extended_wait (int pid, int + else if (ret != new_pid) + internal_error (__FILE__, __LINE__, + _("wait returned unexpected PID %d"), ret); +- else if (!WIFSTOPPED (status) || WSTOPSIG (status) != SIGSTOP) ++ /* In some cases we get 0 for the `SIGSTOP' signal. */ ++ else if (!WIFSTOPPED (status) || ++ (WSTOPSIG (status) != SIGSTOP && WSTOPSIG (status) != 0)) + internal_error (__FILE__, __LINE__, + _("wait returned unexpected status 0x%x"), status); + } +@@ -1007,8 +1009,9 @@ lin_lwp_attach_lwp (ptid_t ptid, int ver + lp->cloned = 1; + } + ++ /* In some cases we get 0 for the `SIGSTOP' signal. */ + gdb_assert (pid == GET_LWP (ptid) +- && WIFSTOPPED (status) && WSTOPSIG (status)); ++ && WIFSTOPPED (status)); + + target_post_attach (pid); + +@@ -1062,13 +1065,14 @@ linux_nat_attach (char *args, int from_t lp->cloned = 1; } - gdb_assert (pid == GET_PID (inferior_ptid) - && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP); -+ /* Do not check `WSTOPSIG (status) == SIGSTOP' as the status may be -+ arbitrary - depending on the signal that stopped the processes. -+ If the process was running we get SIGSTOP, if it was already stopped -+ by SIGSTOP we get 0. The value gets used for `PTRACE_CONT'. */ -+ gdb_assert (pid == GET_PID (inferior_ptid) && WIFSTOPPED (status)); ++ /* In some cases we get 0 for the `SIGSTOP' signal. */ ++ gdb_assert (pid == GET_PID (inferior_ptid) && WIFSTOPPED (status) ++ && (WSTOPSIG (status) == SIGSTOP || WSTOPSIG (status) == 0)); lp->stopped = 1; @@ -46,13 +62,44 @@ diff -u -p -r1.50 linux-nat.c lp->resumed = 1; if (debug_linux_nat) { -Index: gdb-6.5/gdb/testsuite/gdb.base/attachstop.c -=================================================================== -RCS file: gdb-6.5/gdb/testsuite/gdb.base/attachstop.c -diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.c ---- /dev/null 1 Jan 1970 00:00:00 -0000 -+++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.c 17 Sep 2006 21:50:32 -0000 -@@ -0,0 +1,29 @@ +@@ -1509,7 +1513,8 @@ stop_wait_callback (struct lwp_info *lp, + return stop_wait_callback (lp, flush_mask); + } + +- if (WSTOPSIG (status) != SIGSTOP) ++ /* In some cases we get 0 for the `SIGSTOP' signal. */ ++ if (WSTOPSIG (status) != SIGSTOP && WSTOPSIG (status) != 0) + { + if (WSTOPSIG (status) == SIGTRAP) + { +@@ -2093,8 +2098,10 @@ retry: + if (options & __WCLONE) + lp->cloned = 1; + ++ /* In some cases we get 0 for the `SIGSTOP' signal. */ + gdb_assert (WIFSTOPPED (status) +- && WSTOPSIG (status) == SIGSTOP); ++ && (WSTOPSIG (status) == SIGSTOP ++ || WSTOPSIG (status) == 0)); + lp->signalled = 1; + + if (!in_thread_list (inferior_ptid)) +@@ -2195,8 +2202,10 @@ retry: + /* Make sure we don't report a SIGSTOP that we sent + ourselves in an attempt to stop an LWP, unless we + intentionally want to see the SIGSTOP. */ ++ /* In some cases we get 0 for the `SIGSTOP' signal. */ + if (lp->signalled && !intentional_stop +- && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP) ++ && WIFSTOPPED (status) && (WSTOPSIG (status) == SIGSTOP ++ || WSTOPSIG (status) == 0)) + { + if (debug_linux_nat) + fprintf_unfiltered (gdb_stdlog, +diff -u -ruNp gdb-6.5-orig/gdb/testsuite/gdb.base/attachstop.c gdb-6.5/gdb/testsuite/gdb.base/attachstop.c +--- gdb-6.5-orig/gdb/testsuite/gdb.base/attachstop.c 1970-01-01 01:00:00.000000000 +0100 ++++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.c 2006-12-11 23:58:22.000000000 +0100 +@@ -0,0 +1,51 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005 Free Software Foundation, Inc. @@ -74,21 +121,40 @@ diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.c +/* This program is intended to be started outside of gdb, then + manually stopped via a signal. */ + ++#include +#include ++#ifdef USE_THREADS ++#include ++#endif + -+int main () ++static void *func (void *arg) +{ + sleep (10000); /* Ridiculous time, but we will eventually kill it. */ + sleep (10000); /* Second sleep. */ ++ return NULL; ++} ++ ++int main () ++{ ++ ++#ifndef USE_THREADS ++ ++ func (NULL); ++ ++#else ++ ++ pthread_t th; ++ pthread_create (&th, NULL, func, NULL); ++ pthread_join (th, NULL); ++ ++#endif ++ + return 0; +} -Index: gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp -=================================================================== -RCS file: gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp -diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp ---- /dev/null 1 Jan 1970 00:00:00 -0000 -+++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp 17 Sep 2006 21:50:32 -0000 -@@ -0,0 +1,198 @@ +diff -u -ruNp gdb-6.5-orig/gdb/testsuite/gdb.base/attachstop.exp gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp +--- gdb-6.5-orig/gdb/testsuite/gdb.base/attachstop.exp 1970-01-01 01:00:00.000000000 +0100 ++++ gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp 2006-12-12 00:26:39.000000000 +0100 +@@ -0,0 +1,234 @@ +# Copyright 2005-2006 + +# This program is free software; you can redistribute it and/or modify @@ -132,158 +198,194 @@ diff -N gdb-6.5/gdb/testsuite/gdb.base/attachstop.exp +# +#log_user 1 + -+# build the test case -+# -+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { -+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." -+} -+ -+if [get_compiler_info ${binfile}] { -+ return -1 -+} ++proc corefunc { threadtype } { ++ global srcfile ++ global binfile ++ global escapedbinfile ++ global srcdir ++ global subdir ++ global gdb_prompt + -+# Start the program running and then wait for a bit, to be sure -+# that it can be attached to. -+ -+set testpid [eval exec $binfile &] -+exec sleep 2 -+ -+# Stop the program -+remote_exec build "kill -s STOP ${testpid}" -+ -+# Start with clean gdb -+gdb_exit -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+gdb_load ${binfile} -+ -+# Verify that we can attach to the process by first giving its -+# executable name via the file command, and using attach with the -+# process ID. -+ -+set test "set file, before attach1 to stopped process" -+gdb_test_multiple "file $binfile" "$test" { -+ -re "Load new symbol table from.*y or n. $" { -+ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \ -+ "$test (re-read)" ++ if [get_compiler_info ${binfile}] { ++ return -1 + } -+ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" { -+ pass "$test" ++ ++ # Start the program running and then wait for a bit, to be sure ++ # that it can be attached to. ++ ++ set testpid [eval exec $binfile &] ++ exec sleep 2 ++ ++ # Stop the program ++ remote_exec build "kill -s STOP ${testpid}" ++ ++ # Start with clean gdb ++ gdb_exit ++ gdb_start ++ gdb_reinitialize_dir $srcdir/$subdir ++ gdb_load ${binfile} ++ ++ # Verify that we can attach to the process by first giving its ++ # executable name via the file command, and using attach with the ++ # process ID. ++ ++ set test "$threadtype: set file, before attach1 to stopped process" ++ gdb_test_multiple "file $binfile" "$test" { ++ -re "Load new symbol table from.*y or n. $" { ++ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \ ++ "$test (re-read)" ++ } ++ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" { ++ pass "$test" ++ } + } -+} + -+set test "attach1 to stopped, after setting file" -+gdb_test_multiple "attach $testpid" "$test" { -+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { -+ pass "$test" ++ set test "$threadtype: attach1 to stopped, after setting file" ++ gdb_test_multiple "attach $testpid" "$test" { ++ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { ++ pass "$test" ++ } + } -+} + -+gdb_test "bt" ".*sleep.*main.*" "attach1 to stopped bt" ++ if {[string equal $threadtype threaded]} { ++ gdb_test "thread apply all bt" ".*sleep.*clone.*" "$threadtype: attach1 to stopped bt" ++ } else { ++ gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach1 to stopped bt" ++ } + -+# Exit and detach the process. -+ -+gdb_exit ++ # Exit and detach the process. ++ ++ gdb_exit + -+set fileid [open /proc/${testpid}/status r]; -+gets $fileid line1; -+gets $fileid line2; -+close $fileid; ++ set fileid [open /proc/${testpid}/status r]; ++ gets $fileid line1; ++ gets $fileid line2; ++ close $fileid; + -+set test "attach1, exit leaves process stopped" -+if {[string match "*(stopped)*" $line2]} { -+ pass $test -+} else { -+ fail $test -+} ++ set test "$threadtype: attach1, exit leaves process stopped" ++ if {[string match "*(stopped)*" $line2]} { ++ pass $test ++ } else { ++ fail $test ++ } + -+# At this point, the process should still be stopped ++ # At this point, the process should still be stopped + -+gdb_start -+gdb_reinitialize_dir $srcdir/$subdir -+gdb_load ${binfile} ++ gdb_start ++ gdb_reinitialize_dir $srcdir/$subdir ++ gdb_load ${binfile} + -+# Verify that we can attach to the process just by giving the -+# process ID. -+ -+set test "attach2 to stopped, after setting file" -+gdb_test_multiple "attach $testpid" "$test" { -+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { -+ pass "$test" ++ # Verify that we can attach to the process just by giving the ++ # process ID. ++ ++ set test "$threadtype: attach2 to stopped, after setting file" ++ gdb_test_multiple "attach $testpid" "$test" { ++ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { ++ pass "$test" ++ } + } -+} -+ -+gdb_test "bt" ".*sleep.*main.*" "attach2 to stopped bt" -+gdb_breakpoint [gdb_get_line_number "Second sleep"] -+set test "attach2 continue" -+send_gdb "continue\n" -+gdb_expect { -+ -re "Continuing" -+ { pass "continue ($test)" } -+ timeout -+ { fail "continue ($test) (timeout)" } -+} + -+# For this to work we must be sure to consume the "Continuing." -+# message first, or GDB's signal handler may not be in place. -+after 1000 {send_gdb "\003"} -+set test "attach2 stop unbreakable interrupt" -+gdb_expect 4 { -+ -re "Program received signal SIGINT.*$gdb_prompt $" -+ { -+ fail "$test (broke into)" ++ if {[string equal $threadtype threaded]} { ++ gdb_test "thread apply all bt" ".*sleep.*clone.*" "$threadtype: attach2 to stopped bt" ++ } else { ++ gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach2 to stopped bt" + } -+ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $" -+ { -+ fail "$test (broke into)" ++ gdb_breakpoint [gdb_get_line_number "$threadtype: Second sleep"] ++ set test "$threadtype: attach2 continue" ++ send_gdb "continue\n" ++ gdb_expect { ++ -re "Continuing" ++ { pass "continue ($test)" } ++ timeout ++ { fail "continue ($test) (timeout)" } + } -+ timeout -+ { -+ pass $test ++ ++ # For this to work we must be sure to consume the "Continuing." ++ # message first, or GDB's signal handler may not be in place. ++ after 1000 {send_gdb "\003"} ++ set test "$threadtype: attach2 stop unbreakable interrupt" ++ gdb_expect 4 { ++ -re "Program received signal SIGINT.*$gdb_prompt $" ++ { ++ fail "$test (broke into)" ++ } ++ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $" ++ { ++ fail "$test (broke into)" ++ } ++ timeout ++ { ++ pass $test ++ } + } -+} + -+# Continue the program -+remote_exec build "kill -s CONT ${testpid}" ++ # Continue the program ++ remote_exec build "kill -s CONT ${testpid}" + -+# Already sent before: after 1000 {send_gdb "\003"} -+set test "attach2 stop by interrupt" -+gdb_expect { -+ -re "Program received signal SIGINT.*$gdb_prompt $" -+ { -+ pass $test ++ if {[string equal $threadtype threaded]} { ++ # Isn't a bug? kernel-xen-2.6.18-1.2767.el5.i686 ++ set signal_expect "SIGCONT" ++ } else { ++ set signal_expect "SIGINT" + } -+ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $" -+ { -+ pass $test ++ # Already sent before: after 1000 {send_gdb "\003"} ++ set test "$threadtype: attach2 stop by interrupt" ++ gdb_expect { ++ -re "Program received signal $signal_expect,.*$gdb_prompt $" ++ { ++ pass $test ++ } ++ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $" ++ { ++ pass $test ++ } ++ timeout ++ { ++ fail "$test (timeout)" ++ } + } -+ timeout -+ { -+ fail "$test (timeout)" ++ ++ gdb_exit ++ ++ # Avoid some race: ++ exec sleep 2 ++ ++ # At this point, the process should be sleeping ++ ++ set fileid2 [open /proc/${testpid}/status r]; ++ gets $fileid2 line1; ++ gets $fileid2 line2; ++ close $fileid2; ++ ++ set test "$threadtype: attach2, exit leaves process sleeping" ++ if {[string match "*(sleeping)*" $line2]} { ++ pass $test ++ } else { ++ fail $test + } -+} + -+gdb_exit ++ # Make sure we don't leave a process around to confuse ++ # the next test run (and prevent the compile by keeping ++ # the text file busy), in case the "set should_exit" didn't ++ # work. ++ ++ remote_exec build "kill -9 ${testpid}" ++} + -+# At this point, the process should be sleeping ++# build the test case first without threads ++# ++if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { ++ gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail." ++} + -+set fileid2 [open /proc/${testpid}/status r]; -+gets $fileid2 line1; -+gets $fileid2 line2; -+close $fileid2; ++corefunc nonthreaded + -+set test "attach2, exit leaves process sleeping" -+if {[string match "*(sleeping)*" $line2]} { -+ pass $test -+} else { -+ fail $test ++# build the test case first without threads ++# ++if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DUSE_THREADS}] != "" } { ++ gdb_suppress_entire_file "Testcase threaded compile failed, so all tests in this file will automatically fail." +} + -+# Make sure we don't leave a process around to confuse -+# the next test run (and prevent the compile by keeping -+# the text file busy), in case the "set should_exit" didn't -+# work. -+ -+remote_exec build "kill -9 ${testpid}" ++corefunc threaded + +return 0 diff --git a/gdb.spec b/gdb.spec index 993d54d..e1207a1 100644 --- a/gdb.spec +++ b/gdb.spec @@ -11,7 +11,7 @@ Name: gdb Version: 6.5 # The release always contains a leading reserved number, start it at 0. -Release: 18%{?dist} +Release: 19%{?dist} License: GPL Group: Development/Debuggers @@ -47,6 +47,9 @@ Patch2: gdb-6.3-rh-testversion-20041202.patch Patch3: gdb-6.3-rh-testlibunwind-20041202.patch Patch4: gdb-6.3-rh-testlibunwind1fix-20041202.patch +# Cleanup any leftover testsuite processes as it may stuck mock(1) builds. +Source2: gdb-orphanripper.c + # ------------------------------------------ @@ -253,6 +256,7 @@ Patch191: gdb-6.5-bz205551-printf-p.patch Patch192: gdb-6.5-bz206813-cplusplus-symbol-null.patch # Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'. +# Fix attachment also to a threaded stopped process (BZ 219118). Patch193: gdb-6.5-attach-stop.patch # Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337). @@ -499,10 +503,11 @@ ld -v %ifarch %{ix86} x86_64 s390x s390 ppc ia64 ppc64 echo ====================TESTING========================= cd gdb/testsuite +gcc -o ./orphanripper %{SOURCE2} -Wall # Need to use a single --ignore option, second use overrides first. # "chng-syms.exp" for possibly avoiding Linux kernel crash - Bug 207002. # "threadcrash.exp" is incompatible on ia64 with old kernels. -make -k check RUNTESTFLAGS='--ignore "bigcore.exp chng-syms.exp checkpoint.exp threadcrash.exp"' || : +./orphanripper make -k check RUNTESTFLAGS='--ignore "bigcore.exp chng-syms.exp checkpoint.exp threadcrash.exp"' || : for t in sum log; do ln gdb.$t gdb-%{_target_platform}.$t || : done @@ -586,6 +591,10 @@ fi # don't include the files in include, they are part of binutils %changelog +* Tue Dec 12 2006 Jan Kratochvil - 6.5-19 +- Fix attachment also to a threaded stopped process (BZ 219118). +- Cleanup any leftover testsuite processes as it may stuck mock(1) builds. + * Sat Nov 25 2006 Jan Kratochvil - 6.5-18 - Fix readline history for input mode commands like `command' (BZ 215816).