From patchwork Tue Feb 10 19:14:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 5025 Received: (qmail 27513 invoked by alias); 10 Feb 2015 19:14:43 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 27472 invoked by uid 89); 10 Feb 2015 19:14:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=BAYES_00, SPF_HELO_PASS, SPF_SOFTFAIL autolearn=no version=3.3.2 X-HELO: bigwig.baldwin.cx Received: from bigwig.baldwin.cx (HELO bigwig.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 10 Feb 2015 19:14:41 +0000 Received: from ralph.baldwin.cx (pool-173-54-116-245.nwrknj.fios.verizon.net [173.54.116.245]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id B3407B939; Tue, 10 Feb 2015 14:14:38 -0500 (EST) From: John Baldwin To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] Fix signal trampoline detection/unwinding on recent FreeBSD/i386 and FreeBSD/amd64 Date: Tue, 10 Feb 2015 14:14:28 -0500 Message-ID: <1778386.0IyHlhpa5R@ralph.baldwin.cx> User-Agent: KMail/4.14.2 (FreeBSD/10.1-STABLE; KDE/4.14.2; amd64; ; ) In-Reply-To: <54DA3AFE.3060406@redhat.com> References: <11386216.Yv1qECs4Mc@ralph.baldwin.cx> <1836606.R8FOmMR0ZG@ralph.baldwin.cx> <54DA3AFE.3060406@redhat.com> MIME-Version: 1.0 On Tuesday, February 10, 2015 05:08:14 PM Pedro Alves wrote: > On 02/10/2015 02:50 PM, John Baldwin wrote: > >> + sysctl that returns the location of the signal trampoline. > >> + Note that this fetches the address for the current (gdb) process. > >> + This will be correct for other 64-bit processes, but the signal > >> + trampoline location is not properly set for 32-bit processes. */ > > I'm not sure I understand what does "but the signal trampoline > location is not properly set for 32-bit processes" means. You mean > it's not properly set because GDB is 64-bit; or it's not properly set > in the kernel; or something else? The sysctl is designed to be used against the target process, but I did not see an easy way to hook into each run and ptrace attach to invoke the sysctl against the inferior directly. Instead, the sysctl is invoked on the running gdb process under the assumption that all binaries using the same OSABI will use the same signal trampoline location (which is true under FreeBSD). However, the case that breaks is if I'm using a 64-bit gdb to debug a 32-bit process. That is, I don't have an easy way to set the i386fbsd_sigtramp_* variables from amd64fbsd-nat.c as there isn't a specific PID I know I can safely query these values from. All that said, that's also a corner case and this patch will at least fix the more common 64-on-64 and 32-on-32 cases. > >> + } > >> + } > >> +#else > > Did you consider making GDB fallback to the #else block at runtime, for the > case GDB that was built against newer FreeBSD headers but is actually > running on older FreeBSD ? In general FreeBSD only supports backwards compatibility rather than forwards compatibility (so a binary built on an older version should generally work on newer versions, but the opposite is not guaranteed). Given that the Os doesn't really provide for newer binaries to run against older kernels, I don't think it is worth extra work in gdb to tailor to that case. I think the updated version below addresses your other comments (thanks!): ChangeLog: 2015-xx-xx John Baldwin * amd64fbsd-nat.c: Include sys/user.h. (_initialize_amd64fbsd_nat): Use the KERN_PROC_SIGTRAMP sysctl to locate the signal trampoline. * i386fbsd-nat.c (_initialize_i386fbsd_nat): Likewise. * amd64fbsd-tdep.c (amd64fbsd_sigcontext_addr): Use get_frame_register. diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c index 1c396e2..762b13f 100644 --- a/gdb/amd64fbsd-nat.c +++ b/gdb/amd64fbsd-nat.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "fbsd-nat.h" @@ -244,6 +245,29 @@ Please report this to ."), SC_RBP_OFFSET = offset; +#ifdef KERN_PROC_SIGTRAMP + /* FreeBSD 9.2 and later provide a kern.proc.sigtramp. + sysctl that returns the location of the signal trampoline. + Note that this fetches the address for the current (gdb) process. + This will be correct for other 64-bit processes, but the signal + trampoline location is not properly set for 32-bit processes. */ + { + int mib[4]; + struct kinfo_sigtramp kst; + size_t len; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_SIGTRAMP; + mib[3] = getpid (); + len = sizeof (kst); + if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0) + { + amd64fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start; + amd64fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end; + } + } +#else /* FreeBSD provides a kern.ps_strings 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 @@ -264,4 +288,5 @@ Please report this to ."), amd64fbsd_sigtramp_end_addr = ps_strings; } } +#endif } diff --git a/gdb/amd64fbsd-tdep.c b/gdb/amd64fbsd-tdep.c index 2d49cdf..abb0cab 100644 --- a/gdb/amd64fbsd-tdep.c +++ b/gdb/amd64fbsd-tdep.c @@ -37,12 +37,16 @@ static CORE_ADDR amd64fbsd_sigcontext_addr (struct frame_info *this_frame) { + struct gdbarch *gdbarch = get_frame_arch (this_frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR sp; + gdb_byte buf[8]; /* The `struct sigcontext' (which really is an `ucontext_t' on FreeBSD/amd64) lives at a fixed offset in the signal frame. See . */ - sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM); + get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); + sp = extract_unsigned_integer (buf, 8, byte_order); return sp + 16; } diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c index f4951d1..26123d6 100644 --- a/gdb/i386fbsd-nat.c +++ b/gdb/i386fbsd-nat.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "fbsd-nat.h" #include "i386-tdep.h" @@ -148,13 +149,34 @@ _initialize_i386fbsd_nat (void) /* Support debugging kernel virtual memory images. */ bsd_kvm_add_target (i386fbsd_supply_pcb); +#ifdef KERN_PROC_SIGTRAMP + /* FreeBSD 9.2 and later provide a kern.proc.sigtramp. + sysctl that returns the location of the signal trampoline. + Note that this fetches the address for the current (gdb) process, + but should be correct for other processes. */ + { + int mib[4]; + struct kinfo_sigtramp kst; + size_t len; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_SIGTRAMP; + mib[3] = getpid (); + len = sizeof (kst); + if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0) + { + i386fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start; + i386fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end; + } + } +#elif defined(KERN_PS_STRINGS) /* FreeBSD provides a kern.ps_strings 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. */ -#ifdef KERN_PS_STRINGS { int mib[2]; u_long ps_strings;