Broadening to ports@

With respect to this question in my original note:
> Or maybe new gdb has some way to have ptid_get_pid() return the 
> per-thread value?

the answer appears to be "nope, no new magic in gdb for that".


Philip

---------- Forwarded message ----------
Date: Sun, 19 Apr 2015 16:18:07 -0700
From: Philip Guenther <pguent...@proofpoint.com>
To: Pascal Stumpf <pascal.stu...@cubes.de>
Cc: Mark Kettenis <kette...@openbsd.org>
Subject: ports gdb thread handling...


Looks like the gdb in ports needs patching to try ptid_get_lwp() before 
ptid_get_pid() when fetching/setting registers.  For example, diff below 
fixes this for amd64.  Without this it always reports the original 
thread's registers (and thus the same backtrace), but with it I can get 
distinct backtraces like:

(gdb) bt
#0  tmain (arg=0x13b8b2200fcf) at f.c:7
#1  0x000013bad626ba3e in _rthread_start (v=0x13bb143b9000)
    at /usr/src/lib/librthread-clean/rthread.c:145
#2  0x000013bafd3035db in __tfork_thread ()
    at /usr/src/lib/libc-clean/arch/amd64/sys/tfork_thread.S:79
(gdb) info thr
  Id   Target Id         Frame
* 2    thread 1006996    tmain (arg=0x13b8b2200fcf) at f.c:7
  1    thread 1021961    _dl_sigprocmask ()
    at /usr/src/libexec/ld.so-realclean/amd64/ldasm.S:121
(gdb) thread 1
[Switching to thread 1 (thread 1021961)]
#0  _dl_sigprocmask () at /usr/src/libexec/ld.so-realclean/amd64/ldasm.S:121
121             jc      1b               /* error: result = -errno */
(gdb) bt
#0  _dl_sigprocmask () at /usr/src/libexec/ld.so-realclean/amd64/ldasm.S:121
#1  0x000013bba8505352 in _dl_thread_bind_lock (what=0, omask=0x7f7ffffe7474)
    at /usr/src/libexec/ld.so-realclean/dlfcn.c:526
#2  0x000013bba8506a4c in _dl_bind (object=0x13bacf01f800,
    index=<optimized out>)
    at /usr/src/libexec/ld.so-realclean/amd64/rtld_machine.c:393
#3  0x000013bba85028b9 in _dl_bind_start ()
    at /usr/src/libexec/ld.so-realclean/amd64/ldasm.S:167
#4  0x000013bad626b6fe in pthread_join (thread=0x13bb143b9000, retval=0x0)
    at /usr/src/lib/librthread-clean/rthread.c:360
#5  0x000013b8b2100f8a in main () at f.c:18
(gdb)


The other arch files will need the same sort of diff.  Or maybe new gdb 
has some way to have ptid_get_pid() return the per-thread value?

Philip


--- gdb/amd64bsd-nat.c  Thu Feb 19 03:58:07 2015
+++ /tmp/amd64bsd-nat.c Sun Apr 19 16:09:45 2015
@@ -43,13 +43,19 @@
                                   struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int pid;
 
+  /* Cater for systems like OpenBSD, that implement threads as
+     separate processes.  */
+  pid = ptid_get_lwp (inferior_ptid);
+  if (pid == 0)
+    pid = ptid_get_pid (inferior_ptid);
+
   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
     {
       struct reg regs;
 
-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
-                 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
        perror_with_name (_("Couldn't get registers"));
 
       amd64_supply_native_gregset (regcache, &regs, -1);
@@ -61,8 +67,7 @@
     {
       struct fpreg fpregs;
 
-      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
-                 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+      if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
        perror_with_name (_("Couldn't get floating point status"));
 
       amd64_supply_fxsave (regcache, -1, &fpregs);
@@ -77,19 +82,24 @@
                                   struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  int pid;
 
+  /* Cater for systems like OpenBSD, that implement threads as
+     separate processes.  */
+  pid = ptid_get_lwp (inferior_ptid);
+  if (pid == 0)
+    pid = ptid_get_pid (inferior_ptid);
+
   if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
     {
       struct reg regs;
 
-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
-                  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+      if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't get registers"));
 
       amd64_collect_native_gregset (regcache, &regs, regnum);
 
-      if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
-                 (PTRACE_TYPE_ARG3) &regs, 0) == -1)
+      if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't write registers"));
 
       if (regnum != -1)
@@ -100,14 +110,12 @@
     {
       struct fpreg fpregs;
 
-      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
-                 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+      if (ptrace (PT_GETFPREGS, pid, (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, ptid_get_pid (inferior_ptid),
-                 (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
+      if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
        perror_with_name (_("Couldn't write floating point status"));
     }
 }

Reply via email to