Sorry if this appears twice: my webmail client appears to have dropped the original message on the floor.
gdb didn't find threads in corefiles: The support was just missing. The attached patch does the job. Also attached is a small test program which easily generates a corefile with threads in it, if anyone wants to test/commit it. Before and after output below: > petere@rocklobster$ cc -o threadcore -Wall -g -pthread threadcore.c > petere@rocklobster$ ./threadcore > started thread 0 > started thread 1 > started thread 2 > started thread 3 > zsh: bus error (core dumped) ./threadcore > petere@rocklobster$ gdb threadcore threadcore.core > GNU gdb 5.2.1 (FreeBSD) > Copyright 2002 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-undermydesk-freebsd"... > Core was generated by `threadcore'. > Program terminated with signal 10, Bus error. > Reading symbols from /usr/lib/libc_r.so.5...done. > Loaded symbols for /usr/lib/libc_r.so.5 > Reading symbols from /usr/lib/libc.so.5...done. > Loaded symbols for /usr/lib/libc.so.5 > Reading symbols from /usr/libexec/ld-elf.so.1...done. > Loaded symbols for /usr/libexec/ld-elf.so.1 > #0 0x280d5463 in kill () from /usr/lib/libc.so.5 > (gdb) i thr > * 1 process 41359 0x280d5463 in kill () from /usr/lib/libc.so.5 > (gdb) quit > petere@rocklobster$ /usr/src/gnu/usr.bin/binutils/gdb/gdb threadcore > threadcore.core GNU gdb 5.2.1 (FreeBSD) > Copyright 2002 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-undermydesk-freebsd"... > Core was generated by `threadcore'. > Program terminated with signal 10, Bus error. > Reading symbols from /usr/lib/libc_r.so.5...done. > Loaded symbols for /usr/lib/libc_r.so.5 > Reading symbols from /usr/lib/libc.so.5...done. > Loaded symbols for /usr/lib/libc.so.5 > Reading symbols from /usr/libexec/ld-elf.so.1...done. > Loaded symbols for /usr/libexec/ld-elf.so.1 > #0 0x280d5463 in kill () from /usr/lib/libc.so.5 > (gdb) i thr > 7 Process 41359 0x280d5463 in kill () from /usr/lib/libc.so.5 > 6 Process 41359 0x2807b7ec in _thread_kern_sched () from > /usr/lib/libc_r.so.5 5 Process 41359 0x2807b7ec in _thread_kern_sched > () from /usr/lib/libc_r.so.5 4 Process 41359 0x2807b7ec in > _thread_kern_sched () from /usr/lib/libc_r.so.5 3 Process 41359 > 0x2807b7ec in _thread_kern_sched () from /usr/lib/libc_r.so.5 2 > Process 41359 0x2807b7ec in _thread_kern_sched () from > /usr/lib/libc_r.so.5 > * 1 Process 41359 0x280d5463 in kill () from /usr/lib/libc.so.5 > (gdb) Enjoy, Peter.
#include <sys/types.h> #include <signal.h> #include <pthread.h> #include <unistd.h> #include <stdio.h> #include <err.h> void *thr(void *a) { printf("started thread %d\n", (int)a); pause(); return 0; } int main(int argc, char **argv) { const int THREADCOUNT = 4; int i; pthread_t threads[THREADCOUNT]; for (i = 0; i < THREADCOUNT; i++) if (pthread_create(&threads[i], 0, thr, (void *)i) != 0) errx(-1, "cannot create thread"); sleep(1); kill(0, SIGBUS); return 0; }
Index: freebsd-uthread.c =================================================================== RCS file: /pub/FreeBSD/development/FreeBSD-CVS/src/gnu/usr.bin/binutils/gdb/freebsd-uthread.c,v retrieving revision 1.10 diff -u -r1.10 freebsd-uthread.c --- freebsd-uthread.c 4 Jan 2003 17:35:54 -0000 1.10 +++ freebsd-uthread.c 7 Feb 2003 12:34:19 -0000 @@ -46,6 +46,10 @@ #include <sys/stat.h> #include "gdbcore.h" +int coreops_suppress_target = 1; /* Ugh. Override the version in corelow.c. */ +extern struct target_ops core_ops; /* target vector for corelow.c */ +static struct target_ops orig_core_ops; /* target vector for corelow.c */ + extern int child_suppress_run; extern struct target_ops child_ops; /* target vector for inftarg.c */ @@ -60,6 +64,7 @@ /* Pointer to the next function on the objfile event chain. */ static void (*target_new_objfile_chain) (struct objfile *objfile); +static void freebsd_uthread_find_new_threads (void); static void freebsd_uthread_resume PARAMS ((ptid_t pid, int step, enum target_signal signo)); @@ -472,7 +477,10 @@ if (freebsd_uthread_attaching || TIDGET(inferior_ptid) == 0) { - child_ops.to_fetch_registers (regno); + if (target_has_execution) + child_ops.to_fetch_registers (regno); + else + orig_core_ops.to_fetch_registers (regno); return; } @@ -481,7 +489,10 @@ if (active) { - child_ops.to_fetch_registers (regno); + if (target_has_execution) + child_ops.to_fetch_registers (regno); + else + orig_core_ops.to_fetch_registers (regno); return; } @@ -501,8 +512,12 @@ for (regno = first_regno; regno <= last_regno; regno++) { - if (regmap[regno] == -1) - child_ops.to_fetch_registers (regno); + if (regmap[regno] == -1) { + if (target_has_execution) + child_ops.to_fetch_registers (regno); + else + orig_core_ops.to_fetch_registers (regno); + } else if (thread) supply_register (regno, (char*) ®base[regmap[regno]]); @@ -683,6 +698,11 @@ LOOKUP_VALUE(PS_RUNNING); LOOKUP_VALUE(PS_DEAD); + if (!target_has_execution) { + read_thread_offsets(); + freebsd_uthread_find_new_threads(); + } + freebsd_uthread_active = 1; } @@ -731,6 +751,27 @@ return ret; } +static int +freebsd_utcore_thread_alive (ptid_t ptid) +{ + return 1; +} + +static void +freebsd_utcore_attach (char *args, int from_tty) +{ + orig_core_ops.to_attach (args, from_tty); + push_target (&core_ops); + freebsd_uthread_attaching = 1; +} + +static void +freebsd_utcore_detach (char *args, int from_tty) +{ + unpush_target (&core_ops); + orig_core_ops.to_detach (args, from_tty); +} + static void freebsd_uthread_stop (void) { @@ -874,12 +915,41 @@ freebsd_uthread_vec.get_thread_info = freebsd_uthread_get_thread_info; #endif } + + + +static void +init_freebsd_core_ops () +{ + orig_core_ops = core_ops; + core_ops.to_shortname = "freebsd-uthreads (corefile)"; + core_ops.to_longname = "FreeBSD uthreads (corefile)"; + core_ops.to_doc = "FreeBSD user threads support (for corefiles)."; + core_ops.to_has_all_memory = 0; + core_ops.to_has_memory = 1; + core_ops.to_has_stack = 1; + core_ops.to_has_registers = 1; + core_ops.to_has_execution = 0; + core_ops.to_has_thread_control = tc_none; + core_ops.to_magic = OPS_MAGIC; + core_ops.to_pid_to_str = freebsd_uthread_pid_to_str; + core_ops.to_thread_alive = freebsd_utcore_thread_alive; + core_ops.to_attach = freebsd_utcore_attach; + core_ops.to_detach = freebsd_utcore_detach; + core_ops.to_stratum = core_stratum; + core_ops.to_find_new_threads = freebsd_uthread_find_new_threads; + core_ops.to_fetch_registers = freebsd_uthread_fetch_registers; + core_ops.to_sections = 0; + core_ops.to_sections_end = 0; +} void _initialize_freebsd_uthread () { init_freebsd_uthread_ops (); + init_freebsd_core_ops (); add_target (&freebsd_uthread_ops); + add_target (&core_ops); target_new_objfile_chain = target_new_objfile_hook; target_new_objfile_hook = freebsd_uthread_new_objfile;