(unknown charset) gdb has outdated knowledge of signal trampolines

From: (unknown charset) Andriy Gapon <avg_at_FreeBSD.org>
Date: Mon, 25 Nov 2013 12:13:53 +0200
It seems that placement of signal trampolines was changed a while ago.  Possibly
with the introduction of the shared page, but I am not sure.
Unfortunately, neither the gdb in base nor the ports gdb were updated to account
for the new location.

And thus, for example:
(kgdb) bt
#0  thr_kill () at thr_kill.S:3
#1  0x00000008032c89a7 in nsProfileLock::FatalSignalHandler (signo=6,
info=<optimized out>, context=0x7ffffb197630)
    at
/usr/obj/ports/usr/ports/www/firefox/work/mozilla-release/obj-x86_64-unknown-freebsd11.0/toolkit/profile/nsProfileLock.cpp:180
#2  0x0000000800f90596 in handle_signal (actp=<optimized out>, sig=6,
info=0x7ffffb1979a0, ucp=0x7ffffb197630) at /usr/src/lib/libthr/thread/thr_sig.c:237
#3  0x0000000800f9013f in thr_sighandler (sig=6, info=0x0, _ucp=0x7ffffb197630)
at /usr/src/lib/libthr/thread/thr_sig.c:182
#4  0x00007ffffffff003 in ?? ()
#5  0x0000000800f90010 in ?? () at /usr/src/lib/libthr/thread/thr_sig.c:566 from
/lib/libthr.so.3
#6  0x0000000000000000 in ?? ()

Obviously, the gdb is confused after the frame that has 0x00007ffffffff003.

I looked only at amd64 code, but I believe that other platforms (all of them?)
are affected as well.

The following proof of concept patch for the base gdb seems to fix the case of
native debugging on amd64 (target case was not tested).

diff --git a/contrib/gdb/gdb/amd64fbsd-nat.c b/contrib/gdb/gdb/amd64fbsd-nat.c
index f083734..d49dc45 100644
--- a/contrib/gdb/gdb/amd64fbsd-nat.c
+++ b/contrib/gdb/gdb/amd64fbsd-nat.c
_at__at_ -212,24 +212,23 _at__at_ Please report this to <bug-gdb_at_gnu.org>.",

   SC_RBP_OFFSET = offset;

-  /* FreeBSD provides a kern.ps_strings sysctl that we can use to
+  /* FreeBSD provides a kern.usrstack sysctl that we can use to
      locate the sigtramp.  That way we can still recognize a sigtramp
      if its location is changed in a new kernel.  Of course this is
      still based on the assumption that the sigtramp is placed
-     directly under the location where the program arguments and
-     environment can be found.  */
+     directly at usrstack.  */
   {
     int mib[2];
-    long ps_strings;
+    long usrstack;
     size_t len;

     mib[0] = CTL_KERN;
-    mib[1] = KERN_PS_STRINGS;
-    len = sizeof (ps_strings);
-    if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
+    mib[1] = KERN_USRSTACK;
+    len = sizeof (usrstack);
+    if (sysctl (mib, 2, &usrstack, &len, NULL, 0) == 0)
       {
-	amd64fbsd_sigtramp_start_addr = ps_strings - 32;
-	amd64fbsd_sigtramp_end_addr = ps_strings;
+	amd64fbsd_sigtramp_start_addr = usrstack;
+	amd64fbsd_sigtramp_end_addr = usrstack + 0x20;
       }
   }
 }
diff --git a/contrib/gdb/gdb/amd64fbsd-tdep.c b/contrib/gdb/gdb/amd64fbsd-tdep.c
index e4e02ab..87c1484 100644
--- a/contrib/gdb/gdb/amd64fbsd-tdep.c
+++ b/contrib/gdb/gdb/amd64fbsd-tdep.c
_at__at_ -86,8 +86,8 _at__at_ static int amd64fbsd_r_reg_offset[] =
 };

 /* Location of the signal trampoline.  */
-CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0;
-CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0;
+CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7ffffffff000;
+CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7ffffffff020;

 /* From <machine/signal.h>.  */
 int amd64fbsd_sc_reg_offset[] =

-- 
Andriy Gapon
Received on Mon Nov 25 2013 - 09:14:39 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:44 UTC