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*) &regbase[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;

Reply via email to