This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch 2/3] Fix threading internal error on corrupted memory
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 24 Feb 2011 06:13:59 +0100
- Subject: [patch 2/3] Fix threading internal error on corrupted memory
Hi,
this is the reason of this series, it is a very popular bug:
https://bugzilla.redhat.com/show_bug.cgi?id=677654
It is questionable how it happens but from
https://bugzilla.redhat.com/attachment.cgi?id=478948
https://bugzilla.redhat.com/attachment.cgi?id=478954
one can see
warning: .dynamic section for "..." is not at the expected address (wrong library or version mismatch?)
are probably related.
Hypothesis paragraph only:
I think this internal error will get mostly workarounded by:
[patch] [i386] Fix {,un}prelinked libraries for attach/core-load
http://sourceware.org/ml/gdb-patches/2011-02/msg00630.html
althought not due to a valid page-nonaligned displacement of prelink as all
the bugs above happened on x86_64. It may workaround the problem of this fix
for different on-disk versions (upgraded in the meantime) of libraries. With
the prelink fix they will be mapped approx. at their original location instead
of being mapped to an unexpected random (in prelinked case) or unexpected zero
(in unprelinked case) memory location mangling the memory space.
Providing a testcase which reproduces the problem so one can see it can happen
at least during a regular inferior memory corruption.
No regressions on {x86_64,x86_64-m32,i686}-fedora15-linux-gnu.
Thanks,
Jan
gdb/
2011-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>
* 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 <jan.kratochvil@redhat.com>
* 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"
@@ -111,6 +112,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}
@@ -163,4 +187,13 @@ 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"
+}
+
+
set timeout $prev_timeout