Philip Guenther <[email protected]> writes:

> 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".

Makes sense, I only tested with an old gdb (7.9.1) so far but will take
a look at -current soon.

Pascal, any objection?

>
> Philip
>
> ---------- Forwarded message ----------
> Date: Sun, 19 Apr 2015 16:18:07 -0700
> From: Philip Guenther <[email protected]>
> To: Pascal Stumpf <[email protected]>
> Cc: Mark Kettenis <[email protected]>
> 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"));
>      }
>  }
>


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to