From 5752ad02c2f562bb920d3cdf335808219217e55e Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 20 Mar 2011 22:23:58 +0100 Subject: [PATCH] Fix threading internal error on corrupted memory (BZ 677654). Fix i386 rwatch+awatch before run (BZ 688788, on top of BZ 541866). --- gdb-bz541866-rwatch-before-run.patch | 41 +++++++ gdb-core-thread-internalerr-1of3.patch | 154 +++++++++++++++++++++++++ gdb-core-thread-internalerr-2of3.patch | 102 ++++++++++++++++ gdb-core-thread-internalerr-3of3.patch | 101 ++++++++++++++++ gdb.spec | 15 ++- 5 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 gdb-core-thread-internalerr-1of3.patch create mode 100644 gdb-core-thread-internalerr-2of3.patch create mode 100644 gdb-core-thread-internalerr-3of3.patch diff --git a/gdb-bz541866-rwatch-before-run.patch b/gdb-bz541866-rwatch-before-run.patch index 073b6b9..9e9cb2a 100644 --- a/gdb-bz541866-rwatch-before-run.patch +++ b/gdb-bz541866-rwatch-before-run.patch @@ -11,6 +11,47 @@ Index: gdb-7.2.50.20110117/gdb/config/i386/linux64.mh NAT_CDEPS = $(srcdir)/proc-service.list # The dynamically loaded libthread_db needs access to symbols in the +--- gdb-7.2/gdb/config/i386/linux.mh-orig 2010-06-11 14:08:51.000000000 +0200 ++++ gdb-7.2/gdb/config/i386/linux.mh 2011-03-18 12:00:32.000000000 +0100 +@@ -1,6 +1,6 @@ + # Host: Intel 386 running GNU/Linux. + +-NAT_FILE= config/nm-linux.h ++NAT_FILE= nm-linux.h + NATDEPFILES= inf-ptrace.o fork-child.o \ + i386-nat.o i386-linux-nat.o \ + proc-service.o linux-thread-db.o \ +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ gdb-7.1.90.20100711/gdb/config/i386/nm-linux.h 2010-07-13 19:02:28.000000000 +0200 +@@ -0,0 +1,28 @@ ++/* Native support for GNU/Linux i386. ++ ++ Copyright 2010 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ 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 . */ ++ ++#ifndef NM_LINUX_H ++#define NM_LINUX_H ++ ++#include "config/nm-linux.h" ++ ++/* Red Hat backward compatibility with gdb-6.8. */ ++#define target_can_use_hardware_watchpoint(type, cnt, ot) 1 ++ ++#endif /* NM_LINUX64_H */ Index: gdb-7.2.50.20110117/gdb/config/i386/nm-linux64.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 diff --git a/gdb-core-thread-internalerr-1of3.patch b/gdb-core-thread-internalerr-1of3.patch new file mode 100644 index 0000000..0042fee --- /dev/null +++ b/gdb-core-thread-internalerr-1of3.patch @@ -0,0 +1,154 @@ +http://sourceware.org/ml/gdb-patches/2011-02/msg00679.html +Subject: Re: [patch 1/3] Code cleanup: gdb.threads/gcore-thread.exp + +On Thu, 24 Feb 2011 08:20:09 +0100, Joel Brobecker wrote: +> Just a thought: Do we really need to worry about restoring +> the timeout at the end of the testcase, given that this is +> automatically done at the start of each testcase (see gdb.exp: +> gdb_init)? + +I see now: + Re: [RFA/testsuite] Reset the timeout duration at the start of each testcase. + http://sourceware.org/ml/gdb-patches/2010-02/msg00202.html + commit 501c57da40fd27c8036a5fc995f750b0559272ad + +Patch updated. + + +Thanks, +Jan + + +gdb/testsuite/ +2011-02-24 Jan Kratochvil + + * gdb.threads/gcore-thread.exp ($testfile): Match it the .exp + filename. + ($srcfile): Preserve the original value. + ($testfile): Match it the .exp filename. + ($corefile): New variable. Substitute it around. + Use clean_restart. + ($prev_timeout): Remove. + (load_core): Move core loading into this proc. + Fix restore of $timeout if load_core fails. + +--- a/gdb/testsuite/gdb.threads/gcore-thread.exp ++++ b/gdb/testsuite/gdb.threads/gcore-thread.exp +@@ -21,11 +21,11 @@ if $tracelevel then { + strace $tracelevel + } + +- + # Single-threaded test case +-set testfile "pthreads" +-set srcfile ${testfile}.c +-set binfile ${objdir}/${subdir}/gcore-${testfile} ++set testfile "gcore-thread" ++set srcfile pthreads.c ++set binfile ${objdir}/${subdir}/${testfile} ++set corefile ${objdir}/${subdir}/${testfile}.test + + if [istarget "*-*-linux"] then { + set target_cflags "-D_MIT_POSIX_THREADS" +@@ -41,10 +41,7 @@ if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executab + + # Start with a fresh gdb. + +-gdb_exit +-gdb_start +-gdb_reinitialize_dir $srcdir/$subdir +-gdb_load ${binfile} ++clean_restart ${testfile} + + # regexp for "horizontal" text (i.e. doesn't include newline or + # carriage return) +@@ -53,7 +50,6 @@ set horiz "\[^\n\r\]*" + # regexp for newline + set nl "\[\r\n\]+" + +-set prev_timeout $timeout + set timeout 30 + + gdb_test_multiple "help gcore" "help gcore" { +@@ -92,10 +88,9 @@ delete_breakpoints + gdb_breakpoint "thread2" + gdb_test "continue" "Continuing.*Breakpoint.* thread2 .*" "thread 2 is running" + +-set escapedfilename [string_to_regexp ${objdir}/${subdir}/gcore.test] ++set escapedfilename [string_to_regexp $corefile] + # Drop corefile +-gdb_test_multiple "gcore ${objdir}/${subdir}/gcore.test" \ +- "save a corefile" \ ++gdb_test_multiple "gcore $corefile" "save a corefile" \ + { + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass "save a corefile" +@@ -114,31 +109,38 @@ if {!$core_supported} { + return -1 + } + ++ + # Now restart gdb and load the corefile. +-gdb_exit +-gdb_start +-gdb_reinitialize_dir $srcdir/$subdir +-gdb_load ${binfile} +- +-gdb_test_multiple "core ${objdir}/${subdir}/gcore.test" \ +- "re-load generated corefile" { +- -re ".* is not a core dump:.*$gdb_prompt $" { +- fail "re-load generated corefile (bad file format)" +- # No use proceeding from here. +- return; +- } +- -re ".*: No such file or directory.*$gdb_prompt $" { +- fail "re-load generated corefile (file not found)" +- # No use proceeding from here. +- return; +- } +- -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" { +- fail "re-load generated corefile (incomplete note section)" +- } +- -re "Core was generated by .*$gdb_prompt $" { +- pass "re-load generated corefile" ++clean_restart ${testfile} ++ ++proc load_core { corefile } { ++ global gdb_prompt ++ ++ gdb_test_multiple "core $corefile" \ ++ "re-load generated corefile" { ++ -re " is not a core dump:.*\r\n$gdb_prompt $" { ++ fail "re-load generated corefile (bad file format)" ++ # No use proceeding from here. ++ return 0; ++ } ++ -re ": No such file or directory.*\r\n$gdb_prompt $" { ++ fail "re-load generated corefile (file not found)" ++ # No use proceeding from here. ++ return 0; ++ } ++ -re "Couldn't find .* registers in core file.*\r\n$gdb_prompt $" { ++ fail "re-load generated corefile (incomplete note section)" ++ } ++ -re "Core was generated by .*\r\n$gdb_prompt $" { ++ pass "re-load generated corefile" ++ } + } +- } ++ return 1 ++} ++ ++if ![load_core $corefile] { ++ return ++} + + # FIXME: now what can we test about the thread state? + # We do not know for certain that there should be at least +@@ -158,5 +160,3 @@ gdb_test "info threads" ".* thread2 .*" \ + + gdb_test "info threads" ".*${nl}\\* ${horiz} thread2 .*" \ + "thread2 is current thread in corefile" +- +-set timeout $prev_timeout + diff --git a/gdb-core-thread-internalerr-2of3.patch b/gdb-core-thread-internalerr-2of3.patch new file mode 100644 index 0000000..a01f1d1 --- /dev/null +++ b/gdb-core-thread-internalerr-2of3.patch @@ -0,0 +1,102 @@ +http://sourceware.org/ml/gdb-patches/2011-02/msg00680.html +Subject: [patch 2/3] Fix threading internal error on corrupted memory [rediff] + +[rediff] + +gdb/ +2011-02-24 Jan Kratochvil + + * linux-thread-db.c (find_new_threads_callback): Exit on zero TI_TID + even if !TARGET_HAS_EXECUTION. + +gdb/testsuite/ +2011-02-24 Jan Kratochvil + + * gdb.threads/gcore-thread.exp ($core0file): New variable. + (clear __stack_user.next, clear stack_used.next) + (save a zeroed-threads corefile): New test. + Call core_load for $core0file. + (zeroed-threads cannot be listed): New test. + +--- a/gdb/linux-thread-db.c ++++ b/gdb/linux-thread-db.c +@@ -1335,7 +1335,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data) + if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) + return 0; /* A zombie -- ignore. */ + +- if (ti.ti_tid == 0 && target_has_execution) ++ if (ti.ti_tid == 0) + { + /* A thread ID of zero means that this is the main thread, but + glibc has not yet initialized thread-local storage and the +@@ -1347,10 +1347,13 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data) + need this glibc bug workaround. */ + info->need_stale_parent_threads_check = 0; + +- err = info->td_thr_event_enable_p (th_p, 1); +- if (err != TD_OK) +- error (_("Cannot enable thread event reporting for LWP %d: %s"), +- (int) ti.ti_lid, thread_db_err_str (err)); ++ if (target_has_execution) ++ { ++ err = info->td_thr_event_enable_p (th_p, 1); ++ if (err != TD_OK) ++ error (_("Cannot enable thread event reporting for LWP %d: %s"), ++ (int) ti.ti_lid, thread_db_err_str (err)); ++ } + + return 0; + } +--- a/gdb/testsuite/gdb.threads/gcore-thread.exp ++++ b/gdb/testsuite/gdb.threads/gcore-thread.exp +@@ -26,6 +26,7 @@ set testfile "gcore-thread" + set srcfile pthreads.c + set binfile ${objdir}/${subdir}/${testfile} + set corefile ${objdir}/${subdir}/${testfile}.test ++set core0file ${objdir}/${subdir}/${testfile}0.test + + if [istarget "*-*-linux"] then { + set target_cflags "-D_MIT_POSIX_THREADS" +@@ -110,6 +111,29 @@ if {!$core_supported} { + } + + ++# Test the uninitialized thread list. ++# Provide the case of glibc td_thr_get_info handling of: ++# /* Special case for the main thread before initialization. */ ++ ++foreach symbol {__stack_user stack_used} { ++ set test "clear ${symbol}.next" ++ gdb_test_multiple "p *(void **) &${symbol} = 0" $test { ++ -re " = \\(void \\*\\) 0x0\r\n$gdb_prompt $" { ++ pass $test ++ } ++ -re "No symbol \"${symbol}\" in current context\\.\r\n$gdb_prompt $" { ++ xfail $test ++ # Do not do the verification. ++ set core0file "" ++ } ++ } ++} ++ ++if {"$core0file" != ""} { ++ gdb_test "gcore $core0file" "Saved corefile .*" "save a zeroed-threads corefile" ++} ++ ++ + # Now restart gdb and load the corefile. + clean_restart ${testfile} + +@@ -160,3 +184,11 @@ gdb_test "info threads" ".* thread2 .*" \ + + gdb_test "info threads" ".*${nl}\\* ${horiz} thread2 .*" \ + "thread2 is current thread in corefile" ++ ++ ++# Test the uninitialized thread list. ++ ++if {"$core0file" != "" && [load_core $core0file]} { ++ ++ gdb_test "info threads" "Cannot find new threads: .*" "zeroed-threads cannot be listed" ++} + diff --git a/gdb-core-thread-internalerr-3of3.patch b/gdb-core-thread-internalerr-3of3.patch new file mode 100644 index 0000000..88e2d8c --- /dev/null +++ b/gdb-core-thread-internalerr-3of3.patch @@ -0,0 +1,101 @@ +http://sourceware.org/ml/gdb-patches/2011-02/msg00675.html +Subject: [patch 3/3] Display core reasons even during thread error + +[ rediff ] + +Hi, + +this is mostly unrelated. But after the patch 2/3 it will still FAIL: + Loaded symbols for /lib64/ld-linux-x86-64.so.2 + Cannot find new threads: debugger service failed + (gdb) FAIL: gdb.threads/gcore-thread.exp: re-load generated corefile + +as it is a common bug I dislike for years I have fixed it here: + Loaded symbols for /lib64/ld-linux-x86-64.so.2 + Cannot find new threads: debugger service failed + Core was generated by `.../gdb/testsuite/gdb.threads/gcore-thread'. + Program terminated with signal 5, Trace/breakpoint trap. + #0 thread2 (arg=0xdeadbeef) at ./gdb.threads/pthreads.c:91 + 91 int k = 0; + (gdb) PASS: gdb.threads/gcore-thread.exp: re-load generated corefile + +No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu. + + +Thanks, +Jan + + +gdb/ +2011-02-24 Jan Kratochvil + + * corelow.c: Include wrapper.h. + (core_open): Call now gdb_target_find_new_threads. + * wrapper.c: Include target.h. + (gdb_target_find_new_threads): New. + * wrapper.h (gdb_target_find_new_threads): New declaration. + +--- a/gdb/corelow.c ++++ b/gdb/corelow.c +@@ -47,6 +47,7 @@ + #include "auxv.h" + #include "elf/common.h" + #include "gdbcmd.h" ++#include "wrapper.h" + + + #ifndef O_LARGEFILE +@@ -428,7 +429,7 @@ core_open (char *filename, int from_tty) + may be a thread_stratum target loaded on top of target core by + now. The layer above should claim threads found in the BFD + sections. */ +- target_find_new_threads (); ++ gdb_target_find_new_threads (); + + p = bfd_core_file_failing_command (core_bfd); + if (p) +--- a/gdb/wrapper.c ++++ b/gdb/wrapper.c +@@ -21,6 +21,7 @@ + #include "exceptions.h" + #include "wrapper.h" + #include "ui-out.h" ++#include "target.h" + + int + gdb_parse_exp_1 (char **stringptr, struct block *block, int comma, +@@ -161,3 +162,24 @@ gdb_value_struct_elt (struct ui_out *uiout, struct value **result, + return GDB_RC_FAIL; + return GDB_RC_OK; + } ++ ++/* Call target_find_new_threads without throwing exception. Exception is ++ printed if it got thrown. */ ++ ++int ++gdb_target_find_new_threads (void) ++{ ++ volatile struct gdb_exception except; ++ ++ TRY_CATCH (except, RETURN_MASK_ERROR) ++ { ++ target_find_new_threads (); ++ } ++ ++ if (except.reason < 0) ++ { ++ exception_print (gdb_stderr, except); ++ return 0; ++ } ++ return 1; ++} +--- a/gdb/wrapper.h ++++ b/gdb/wrapper.h +@@ -48,4 +48,6 @@ extern int gdb_value_ind (struct value *val, struct value ** rval); + + extern int gdb_parse_and_eval_type (char *, int, struct type **); + ++extern int gdb_target_find_new_threads (void); ++ + #endif /* wrapper.h */ + diff --git a/gdb.spec b/gdb.spec index 488c69a..fee9d75 100644 --- a/gdb.spec +++ b/gdb.spec @@ -27,7 +27,7 @@ Version: 7.2.50.20110320 # 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: 29%{?_with_upstream:.upstream}%{?dist} +Release: 30%{?_with_upstream:.upstream}%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain Group: Development/Debuggers @@ -466,6 +466,7 @@ Patch408: gdb-ppc-power7-test.patch Patch412: gdb-unused-revert.patch # Fix i386+x86_64 rwatch+awatch before run, regression against 6.8 (BZ 541866). +# Fix i386 rwatch+awatch before run (BZ 688788, on top of BZ 541866). #=push+work: It should be fixed properly instead. Patch417: gdb-bz541866-rwatch-before-run.patch @@ -552,6 +553,11 @@ Patch556: gdb-gcc46-stdarg-prologue.patch # Fix attach/core-load of {,un}prelinked i386 libs (bugreport by Michal Toman). Patch571: gdb-prelink-rela.patch +# Fix threading internal error on corrupted memory (BZ 677654). +Patch572: gdb-core-thread-internalerr-1of3.patch +Patch573: gdb-core-thread-internalerr-2of3.patch +Patch574: gdb-core-thread-internalerr-3of3.patch + # [stap] Fix -O2 warnings. Patch576: gdb-stap-warnings.patch @@ -826,6 +832,9 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c %patch555 -p1 %patch556 -p1 %patch571 -p1 +%patch572 -p1 +%patch573 -p1 +%patch574 -p1 %patch576 -p1 %patch577 -p1 @@ -1253,6 +1262,10 @@ fi %{_infodir}/gdb.info* %changelog +* Sun Mar 20 2011 Jan Kratochvil - 7.2.50.20110320-30.fc15 +- Fix threading internal error on corrupted memory (BZ 677654). +- Fix i386 rwatch+awatch before run (BZ 688788, on top of BZ 541866). + * Sun Mar 20 2011 Jan Kratochvil - 7.2.50.20110320-29.fc15 - Rebase to FSF GDB 7.2.50.20110320 (which is a 7.3 pre-release). - Merge archer-sergiodj-stap, the SystemTap probes breakpoints feature.