public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: John Baldwin <jhb@freebsd.org>
To: gdb-patches@sourceware.org
Subject: Fix signal trampoline detection/unwinding on recent FreeBSD/i386 and FreeBSD/amd64
Date: Wed, 04 Feb 2015 15:47:00 -0000	[thread overview]
Message-ID: <11386216.Yv1qECs4Mc@ralph.baldwin.cx> (raw)

This patch fixes two issues with signal frame unwinding on recent FreeBSD/x86:

First, FreeBSD moved the signal trampoline code into a global shared page
exported by the kernel a few releases ago.  To try to make this easier to
detect, FreeBSD added a new per-process sysctl node that exports the starting
and ending address of the signal trampoline code.  This sysctl works on all
platforms that FreeBSD supports no matter where the signal trampoline lives,
but I have only updated i386 and amd64 in this patch.

Second, amd64fbsd_sigcontext_addr was using frame_unwind_register_unsigned to
fetch the stack pointer which resulted in infinite recursion.  I've changed it
to use get_frame_register() to match the sigcontext_addr methods in the
i386-bsd and amd64-linux targets instead.

Changelog:

2015-xx-xx  John Baldwin  <jhb@FreeBSD.org>

	* amd64fbsd-nat.c (_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): Fix infinite recursion.

diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c
index 1c396e2..6227681 100644
--- a/gdb/amd64fbsd-nat.c
+++ b/gdb/amd64fbsd-nat.c
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <sys/sysctl.h>
+#include <sys/user.h>
 #include <machine/reg.h>
 
 #include "fbsd-nat.h"
@@ -244,6 +245,29 @@ Please report this to <bug-gdb@gnu.org>."),
 
   SC_RBP_OFFSET = offset;
 
+#ifdef KERN_PROC_SIGTRAMP
+  /* Newer versions of FreeBSD provide a kern.proc.sigtramp.<pid>
+     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 <bug-gdb@gnu.org>."),
 	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
      <machine/sigframe.h>.  */
-  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;
 }
 \f
diff --git a/gdb/i386fbsd-nat.c b/gdb/i386fbsd-nat.c
index f4951d1..5293f0f 100644
--- a/gdb/i386fbsd-nat.c
+++ b/gdb/i386fbsd-nat.c
@@ -25,6 +25,7 @@
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <sys/sysctl.h>
+#include <sys/user.h>
 
 #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
+  /* Newer versions of FreeBSD provide a kern.proc.sigtramp.<pid>
+     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;

-- 
John Baldwin

             reply	other threads:[~2015-02-04 15:47 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-04 15:47 John Baldwin [this message]
2015-02-10 14:51 ` [PATCH] " John Baldwin
2015-02-10 17:08   ` Pedro Alves
2015-02-10 19:14     ` John Baldwin
2015-02-10 23:34       ` Pedro Alves
2015-02-11  0:01         ` Mark Kettenis
2015-02-11 16:04         ` John Baldwin
2015-02-11 16:40           ` Pedro Alves
2015-02-16 18:25             ` John Baldwin
2015-02-16 22:56               ` Pedro Alves
2015-02-23 16:33                 ` John Baldwin
2015-02-23 16:56                   ` Pedro Alves
     [not found] <2729970.x7obi12nSh@ralph.baldwin.cx>
2015-02-06 20:37 ` Ed Maste

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11386216.Yv1qECs4Mc@ralph.baldwin.cx \
    --to=jhb@freebsd.org \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).