This is not yet complete or debugged, but it improves things. The signals.c patch makes gdb not be confused by the signals that LinuxThreads(sic) uses internally; you can even 'handle LTRESTART nostop' if you prefer (you probably do so prefer). This is a slightly different version of a patch that I attached to bug #698200 in that it gives these signals names that you can pass to 'handle' (the numbers didn't work)
Even so, this doesn't make 'info threads' work. That's what the inf-ptrace.c patch does. Unfortunately, the main thread is listed twice and I haven't found out how to avoid that yet. Also, it makes me wonder why PT_LWPINFO and friends are commented out in <sys/ptrace.h>; they seem to work just fine. Also, this may belong in amd64bsd-nat.c or some other more system-specific file than inf-ptrace.c. And this doesn't make the 'thread' command work, either. For that to work, it's necessary to use the TID (instead of the PID) in many (most? all?) ptrace calls. The middle patch, to amd64bsd-nat.c, does this enough to make 'thread 2' and 'thread apply all bt' work. The main problems I've observed so far are the dual-listing of the main thread, and a repeatable crash when listing threads when not in the main thread: (gdb) thread 2 [Switching to thread 2 (process 15205)] #0 syscall () at ../ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/x86_64/syscall.S:27 27 ../ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/x86_64/syscall.S: No such file or directory. (gdb) info threads Program received signal SIGSEGV, Segmentation fault. 0x00000000004efdf1 in add_thread_object (tp=0x10720a0) at /store/src/gdb-7.4.1/gdb/python/py-inferior.c:247 247 entry->next = inf_obj->threads; (top-gdb) I don't know what this is about yet, but it seems to mean that debugging threads is likely to still be a minefield. oh, and I just noticed another oddity, threads don't become known until you 'info thread': (gdb) thread 2 Thread ID 2 not known. (gdb) info thread [New process 19492] [New process 19492] [New process 19492] Id Target Id Frame 4 process 19492 __pthread_sigsuspend () at ../ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/linuxthreads/pt-sigsuspend.S:24 3 process 19492 0x0000000800b083e9 in poll () at ../sysdeps/unix/syscall-template.S:82 2 process 19492 pthread_start_thread (arg=0x6041a0) at manager.c:260 * 1 process 19492 __pthread_sigsuspend () at ../ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/linuxthreads/pt-sigsuspend.S:24 (gdb) thread 2 [Switching to thread 2 (process 19492)] ... hmmm Anyway, the patches (against gdb-7.4.1-3) (phew, the same in sid, so I haven't been wasting my time.. I forgot to check until now): --- a/gdb/common/signals.c +++ b/gdb/common/signals.c @@ -600,6 +600,15 @@ return SIGINFO; #endif +#if defined(__GLIBC__) && defined(__FreeBSD_kernel__) + case TARGET_SIGNAL_LINUXTHREADS_RESTART: + return 32; + case TARGET_SIGNAL_LINUXTHREADS_CANCEL: + return 33; + case TARGET_SIGNAL_LINUXTHREADS_DEBUG: + return 34; +#endif + default: #if defined (REALTIME_LO) retsig = 0; --- a/include/gdb/signals.def +++ b/include/gdb/signals.def @@ -194,9 +194,9 @@ SET (TARGET_EXC_SOFTWARE, 149, "EXC_SOFTWARE", "Software generated exception") SET (TARGET_EXC_BREAKPOINT, 150, "EXC_BREAKPOINT", "Breakpoint") -SET (TARGET_SIGNAL_LINUXTHREADS_RESTART, 151, "32", "LinuxThreads restart signal") -SET (TARGET_SIGNAL_LINUXTHREADS_CANCEL, 152, "33", "LinuxThreads cancel signal") -SET (TARGET_SIGNAL_LINUXTHREADS_DEBUG, 153, "34", "LinuxThreads debug signal") +SET (TARGET_SIGNAL_LINUXTHREADS_RESTART, 151, "LTRESTART", "LinuxThreads restart signal") +SET (TARGET_SIGNAL_LINUXTHREADS_CANCEL, 152, "LTCANCEL", "LinuxThreads cancel signal") +SET (TARGET_SIGNAL_LINUXTHREADS_DEBUG, 153, "LTDEBUG", "LinuxThreads debug signal") /* If you are adding a new signal, add it just above this comment. */ --- a/gdb/amd64bsd-nat.c +++ b/gdb/amd64bsd-nat.c @@ -35,6 +35,8 @@ #include "inf-ptrace.h" +#define TPIDGET(x) (TIDGET(x) ? TIDGET(x) : PIDGET(x)) + /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers (including the floating-point registers). */ @@ -48,7 +50,7 @@ { struct reg regs; - if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + if (ptrace (PT_GETREGS, TPIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); @@ -61,7 +63,7 @@ { struct fpreg fpregs; - if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + if (ptrace (PT_GETFPREGS, TPIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get floating point status")); @@ -82,13 +84,13 @@ { struct reg regs; - if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + if (ptrace (PT_GETREGS, TPIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't get registers")); amd64_collect_native_gregset (regcache, ®s, regnum); - if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), + if (ptrace (PT_SETREGS, TPIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) ®s, 0) == -1) perror_with_name (_("Couldn't write registers")); @@ -100,13 +102,13 @@ { struct fpreg fpregs; - if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + if (ptrace (PT_GETFPREGS, TPIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't get floating point status")); amd64_collect_fxsave (regcache, regnum, &fpregs); - if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + if (ptrace (PT_SETFPREGS, TPIDGET (inferior_ptid), (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) perror_with_name (_("Couldn't write floating point status")); } --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -25,6 +25,7 @@ #include "terminal.h" #include "gdbcore.h" #include "regcache.h" +#include "ptid.h" #include "gdb_assert.h" #include "gdb_string.h" @@ -36,6 +37,12 @@ #include "inf-child.h" #include "gdbthread.h" +#if defined(__GLIBC__) && defined(__FreeBSD_kernel__) +#define PT_LWPINFO 13 /* Info about the LWP that stopped. */ +#define PT_GETNUMLWPS 14 /* get total number of threads */ +#define PT_GETLWPLIST 15 /* get thread list */ +#endif + #ifdef PT_GET_PROCESS_STATE @@ -618,6 +625,28 @@ return normal_pid_to_str (ptid); } +static void +inf_ptrace_find_new_threads (struct target_ops *ops) +{ +#ifdef PT_GETLWPLIST + int pid = ptid_get_lwp (inferior_ptid), nt; + if (pid == 0) + pid = ptid_get_pid (inferior_ptid); + nt = ptrace(PT_GETNUMLWPS, pid, 0, 0); + if(nt < 0) return; + { + int ti[nt]; + int i; + nt = ptrace(PT_GETLWPLIST, pid, (caddr_t)ti, nt); + for(i=0; i<nt; i++) { + ptid_t gdb_threadid = MERGEPID (pid, ti[i]); + if(!in_thread_list (gdb_threadid) || is_exited (gdb_threadid)) + add_thread (gdb_threadid); + } + } +#endif +} + /* Create a prototype ptrace target. The client can override it with local methods. */ @@ -643,6 +672,7 @@ t->to_pid_to_str = inf_ptrace_pid_to_str; t->to_stop = inf_ptrace_stop; t->to_xfer_partial = inf_ptrace_xfer_partial; + t->to_find_new_threads = inf_ptrace_find_new_threads; return t; } -- To UNSUBSCRIBE, email to debian-bsd-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/20130116025816.gb14...@unpythonic.net