Re: RFC: Re: [patch] Fix for 'info threads' crashes if zombie threads exist

Jan Kratochvil
2006-07-13T13:28:39Z

[-- Attachment #1: Type: text/plain, Size: 805 bytes --]

On Thu, 13 Jul 2006 06:01:35 +0200, Daniel Jacobowitz wrote:
> On Tue, Jun 20, 2006 at 03:07:40PM -0400, Daniel Jacobowitz wrote:
> > I think the real fix to this problem is going to involve less
> > dependence on thread IDs. I've been migrating the code away from that
> > and I'll try to find some time in the next week to finish the job;
> > maybe that will help.
>
> Here's an alternative patch that seems to work for the same test.
> Could one of you let me know if it also helps for the problems you saw?

The test
1.Start print-threads within GDB
2.Set a breakpoint in __pthread_unwind
3.Run the program
4.When the program stops at the breakpoint, run `info threads'

still fails the same way. Logs attached - attached also that patch of mine
fixing/workaround it in some way.

Thanks,
Jan

[-- Attachment #2: print-threads.log --]
[-- Type: text/plain, Size: 4894 bytes --]

+ gdb -nx ../../gdb
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) run -nx print-threads
Starting program: /home/lace/redhat/sources/gdb-clean/gdb -nx print-threads
GNU gdb 6.5.50.20060713-cvs
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) b __pthread_unwind
Function "__pthread_unwind" not defined.
Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 1 (__pthread_unwind) pending.
(gdb) r
Starting program: /home/lace/redhat/sources/gdb-clean/testsuite/gdb.threads/print-threads
[Thread debugging using libthread_db enabled]
[New Thread -1208133952 (LWP 22039)]
Breakpoint 2 at 0x443b0634
Pending breakpoint "__pthread_unwind" resolved
[New Thread -1208136800 (LWP 23163)]
[New Thread -1218626656 (LWP 23164)]
[New Thread -1229120608 (LWP 23165)]
[New Thread -1239610464 (LWP 23166)]
[New Thread -1250100320 (LWP 23167)]
[Switching to Thread -1208136800 (zombie)]

Breakpoint 2, 0x443b0634 in __pthread_unwind () from /lib/libpthread.so.0
(gdb) info threads
6 Thread -1250100320 (LWP 23167) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
5 Thread -1239610464 (LWP 23166) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
4 Thread -1229120608 (LWP 23165) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
3 Thread -1218626656 (LWP 23164) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
1 Thread -1208133952 (LWP 22039) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
Detaching after fork from child process 22039.
Detaching after fork from child process 23161.

Program received signal SIGSEGV, Segmentation fault.
thread_db_map_id2thr (thread_info=0x0, fatal=1) at .././gdb-clean/linux-thread-db.c:318
318 if (thread_info->private->th_valid)
(gdb) bt
#0 thread_db_map_id2thr (thread_info=0x0, fatal=1) at .././gdb-clean/linux-thread-db.c:318
#1 0x0809737e in thread_db_fetch_registers (regno=8) at .././gdb-clean/linux-thread-db.c:1009
#2 0x080e1739 in regcache_raw_read (regcache=0x9b83210, regnum=8, buf=0xbfe734a0 "\b") at regcache.c:590
#3 0x080e3482 in deprecated_read_register_gen (regnum=8, buf=0xbfe734a0 "\b") at regcache.c:659
#4 0x080e354d in read_register (regnum=8) at regcache.c:944
#5 0x080e37cb in read_pc_pid (ptid={pid = 22039, lwp = 23163, tid = -1208136800}) at regcache.c:1080
#6 0x080e3845 in read_pc () at regcache.c:1093
#7 0x0811b50e in switch_to_thread (ptid={pid = 22039, lwp = 23163, tid = -1208136800}) at thread.c:467
#8 0x0811bc43 in info_threads_command (arg=0x0, from_tty=1) at thread.c:435
#9 0x080840b3 in execute_command (p=0x9b4d134 "", from_tty=1) at top.c:452
#10 0x081203af in command_handler (command=0x9b4d128 "info threads") at event-top.c:512
#11 0x0812110d in command_line_handler (rl=0x9baf7b0 "info threads") at event-top.c:797
#12 0x081d1052 in rl_callback_read_char () at callback.c:204
#13 0x0812057b in rl_callback_read_char_wrapper (client_data=0x0) at event-top.c:178
#14 0x0811ff00 in handle_file_event (event_file_desc=0) at event-loop.c:730
#15 0x0811f3c9 in process_event () at event-loop.c:343
#16 0x0811fb85 in gdb_do_one_event (data=0x0) at event-loop.c:380
#17 0x0811c9b3 in catch_errors (func=0x811fa70 <gdb_do_one_event>, func_args=0x0, errstring=0x8265265 "", mask=6)
at exceptions.c:515
#18 0x080c62d9 in tui_command_loop (data=0x0) at .././gdb-clean/tui/tui-interp.c:151
#19 0x0811cfbf in current_interp_command_loop () at interps.c:278
#20 0x0807d44b in captured_command_loop (data=0x0) at .././gdb-clean/main.c:101
#21 0x0811c9b3 in catch_errors (func=0x807d440 <captured_command_loop>, func_args=0x0, errstring=0x8265265 "", mask=6)
at exceptions.c:515
#22 0x0807dc44 in captured_main (data=0xbfe73944) at .././gdb-clean/main.c:834
#23 0x0811c9b3 in catch_errors (func=0x807d480 <captured_main>, func_args=0xbfe73944, errstring=0x8265265 "", mask=6)
at exceptions.c:515
#24 0x0807d431 in gdb_main (args=0xbfe73944) at .././gdb-clean/main.c:843
#25 0x0807d3f5 in main (argc=Cannot access memory at address 0x5617
) at gdb.c:35
(gdb) quit
The program is running. Exit anyway? (y or n)

[-- Attachment #3: print-threads-patched.log --]
[-- Type: text/plain, Size: 2564 bytes --]

+ gdb -nx ../../gdb
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) run -nx print-threads
Starting program: /home/lace/redhat/sources/gdb-clean/gdb -nx print-threads
GNU gdb 6.5.50.20060713-cvs
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) b __pthread_unwind
Function "__pthread_unwind" not defined.
Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 1 (__pthread_unwind) pending.
(gdb) r
Starting program: /home/lace/redhat/sources/gdb-clean/testsuite/gdb.threads/print-threads
[Thread debugging using libthread_db enabled]
[New Thread -1208396096 (LWP 25838)]
Breakpoint 2 at 0x443b0634
Pending breakpoint "__pthread_unwind" resolved
[New Thread -1208398944 (LWP 26959)]
[New Thread -1218888800 (LWP 26960)]
[New Thread -1229382752 (LWP 26961)]
[New Thread -1239872608 (LWP 26962)]
[New Thread -1250362464 (LWP 26963)]
[Switching to Thread -1208398944 (zombie)]

Breakpoint 2, 0x443b0634 in __pthread_unwind () from /lib/libpthread.so.0
(gdb) info threads
6 Thread -1250362464 (LWP 26963) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
5 Thread -1239872608 (LWP 26962) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
4 Thread -1229382752 (LWP 26961) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
3 Thread -1218888800 (LWP 26960) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
* 2 Thread -1208398944 (zombie) 0x443b0634 in __pthread_unwind () from /lib/libpthread.so.0
1 Thread -1208396096 (LWP 25838) 0x44031822 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) quit
The program is running. Exit anyway? (y or n) Detaching after fork from child process 25838.
Detaching after fork from child process 26957.

Program exited normally.
(gdb) quit

[-- Attachment #4: gdb-cvs20060620-pthread_exit.patch --]
[-- Type: text/plain, Size: 1415 bytes --]

Index: linux-thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.16
diff -u -p -r1.16 linux-thread-db.c
--- linux-thread-db.c 5 May 2006 22:42:43 -0000 1.16
+++ linux-thread-db.c 20 Jun 2006 17:51:01 -0000
@@ -1006,6 +1006,9 @@ thread_db_fetch_registers (int regno)
}

thread_info = find_thread_pid (inferior_ptid);
+ if (!thread_info)
+ error (_("Stopped at dead thread %ld; should not happen."),
+ (long) GET_THREAD (inferior_ptid));
thread_db_map_id2thr (thread_info, 1);

err = td_thr_getgregs_p (&thread_info->private->th, gregset);
@@ -1127,6 +1130,8 @@ thread_db_thread_alive (ptid_t ptid)
struct thread_info *thread_info;
thread_info = find_thread_pid (ptid);

+ if (!thread_info)
+ return 0;
thread_db_map_id2thr (thread_info, 0);
if (!thread_info->private->th_valid)
return 0;
@@ -1145,9 +1150,9 @@ thread_db_thread_alive (ptid_t ptid)
thread_info->private->ti_valid = 1;
}

- if (thread_info->private->ti.ti_state == TD_THR_UNKNOWN
- || thread_info->private->ti.ti_state == TD_THR_ZOMBIE)
- return 0; /* A zombie thread. */
+ /* Never 0 on TD_THR_ZOMBIE to be able to trace pthread_exit(3). */
+ if (thread_info->private->ti.ti_state == TD_THR_UNKNOWN)
+ return 0; /* A disappeared thread. */

return 1;
}