Date: Mon, 25 Nov 2013 12:13:53 +0200 From: Andriy Gapon <avg@FreeBSD.org> To: FreeBSD Current <freebsd-current@FreeBSD.org> Cc: Konstantin Belousov <kib@FreeBSD.org>, Luca Pizzamiglio <luca.pizzamiglio@gmail.com> Subject: gdb has outdated knowledge of signal trampolines Message-ID: <529322E1.1060105@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
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 @@ -212,24 +212,23 @@ Please report this to <bug-gdb@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 @@ -86,8 +86,8 @@ 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?529322E1.1060105>