public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap: make exception-related breakpoints use stap probes when available this is untested; it needs the probe arguments to work first
@ 2011-02-10 18:42 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2011-02-10 18:42 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap has been updated
       via  0fec3a3d8f23a141e2647927375981029355ab3f (commit)
      from  1b16efd7055bbe6ff5029ecc36df9b8a04704799 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 0fec3a3d8f23a141e2647927375981029355ab3f
Author: Tom Tromey <tromey@redhat.com>
Date:   Thu Feb 10 11:41:30 2011 -0700

    make exception-related breakpoints use stap probes when available
    this is untested; it needs the probe arguments to work first

-----------------------------------------------------------------------

Summary of changes:
 gdb/breakpoint.c |   15 +++++++++++
 gdb/infrun.c     |   75 ++++++++++++++++++++++++++++++++++++++++++++++++------
 gdb/stap-probe.c |   67 ++++++++++++++++++++++++++++++++++++-----------
 gdb/stap-probe.h |   14 ++++++++++
 4 files changed, 147 insertions(+), 24 deletions(-)

First 500 lines of diff:
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 3c59f11..8390be8 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -63,6 +63,7 @@
 #include "xml-syscall.h"
 #include "parser-defs.h"
 #include "gdb_regex.h"
+#include "stap-probe.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -2269,6 +2270,20 @@ create_exception_master_breakpoint (void)
   ALL_OBJFILES (objfile)
     {
       struct minimal_symbol *debug_hook;
+      const struct stap_probe *probe;
+
+      probe = find_probe_in_objfile (objfile, "libgcc", "unwind");
+      if (probe != NULL)
+	{
+	  struct breakpoint *b;
+	  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+	  b = create_internal_breakpoint (gdbarch, probe->address,
+					  bp_exception_master);
+	  b->addr_string = xstrdup ("probe:libgcc:unwind");
+	  b->enable_state = bp_disabled;
+	  continue;
+	}
 
       debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile);
       if (debug_hook != NULL)
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 6fdd9df..8bf8a57 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -54,6 +54,8 @@
 #include "inline-frame.h"
 #include "jit.h"
 #include "tracepoint.h"
+#include "stap-probe.h"
+#include "objfiles.h"
 
 /* Prototypes for local functions */
 
@@ -2239,7 +2241,7 @@ static void insert_step_resume_breakpoint_at_sal (struct gdbarch *,
 						  struct frame_id);
 static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
 static void check_exception_resume (struct execution_control_state *,
-				    struct frame_info *, struct symbol *);
+				    struct frame_info *);
 
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
@@ -4166,12 +4168,7 @@ process_event_stop_test:
 	    insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
 	  }
 	else
-	  {
-	    struct symbol *func = get_frame_function (frame);
-
-	    if (func)
-	      check_exception_resume (ecs, frame, func);
-	  }
+	  check_exception_resume (ecs, frame);
 	keep_going (ecs);
 	return;
 
@@ -5246,15 +5243,77 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
     }
 }
 
+/* A helper for check_exception_resume that sets an
+   exception-breakpoint based on a SystemTap probe.  */
+
+static void
+insert_exception_resume_from_probe (struct thread_info *tp,
+				    const struct stap_probe *probe,
+				    struct objfile *objfile,
+				    struct frame_info *frame)
+{
+  int n_probes;
+  struct value *arg_value;
+  CORE_ADDR handler;
+  struct breakpoint *bp;
+
+  /* This is really a "can't happen", but we are paranoid.  */
+  if (!objfile->sf || !objfile->sf->sym_probe_fns)
+    return;
+
+  n_probes
+    = objfile->sf->sym_probe_fns->sym_get_probe_argument_count (objfile,
+								probe);
+  if (n_probes < 2)
+    return;
+ 
+  /* We are interested in the second argument to the probe.  */
+  arg_value
+    = objfile->sf->sym_probe_fns->sym_evaluate_probe_argument (objfile,
+							       probe,
+							       frame,
+							       1);
+  handler = value_as_address (arg_value);
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+			"infrun: exception resume at %lx\n",
+			(unsigned long) handler);
+
+  bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
+				       handler, bp_exception_resume);
+  bp->thread = tp->num;
+  inferior_thread ()->control.exception_resume_breakpoint = bp;
+}
+
 /* This is called when an exception has been intercepted.  Check to
    see whether the exception's destination is of interest, and if so,
    set an exception resume breakpoint there.  */
 
 static void
 check_exception_resume (struct execution_control_state *ecs,
-			struct frame_info *frame, struct symbol *func)
+			struct frame_info *frame)
 {
   struct gdb_exception e;
+  struct objfile *objfile;
+  const struct stap_probe *probe;
+  struct symbol *func;
+
+  /* First see if this exception unwinding breakpoint was set via a
+     SystemTap probe point.  If so, the probe has two arguments: the
+     CFA and the HANDLER.  We ignore the CFA, extract the handler, and
+     set a breakpoint there.  */
+  probe = find_probe_by_pc (get_frame_pc (frame), &objfile);
+  if (probe)
+    {
+      insert_exception_resume_from_probe (ecs->event_thread, probe,
+					  objfile, frame);
+      return;
+    }
+
+  func = get_frame_function (frame);
+  if (!func)
+    return;
 
   TRY_CATCH (e, RETURN_MASK_ERROR)
     {
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 7230a49..ccca946 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -265,6 +265,32 @@ info_probes_command (char *arg, int from_tty)
 
 \f
 
+const struct stap_probe *
+find_probe_in_objfile (struct objfile *objfile,
+		       const char *provider,
+		       const char *name)
+{
+  const struct stap_probe *probes;
+  int i, num_probes;
+
+  if (! objfile->sf || ! objfile->sf->sym_probe_fns)
+    return NULL;
+
+  probes = objfile->sf->sym_probe_fns->sym_get_probes (objfile, &num_probes);
+  for (i = 0; i < num_probes; ++i)
+    {
+      if (strcmp (probes[i].provider, provider) != 0)
+	continue;
+
+      if (strcmp (probes[i].name, name) != 0)
+	continue;
+
+      return &probes[i];
+    }
+
+  return NULL;
+}
+
 struct symtabs_and_lines
 parse_stap_probe (char **argptr)
 {
@@ -370,22 +396,10 @@ parse_stap_probe (char **argptr)
 
 \f
 
-/* This is called to compute the value of one of the $_marker_arg*
-   convenience variables.  */
-
-static struct value *
-compute_marker_arg (struct gdbarch *arch, struct internalvar *ivar,
-		    void *data)
+const struct stap_probe *
+find_probe_by_pc (CORE_ADDR pc, struct objfile **objfile_out)
 {
-  struct frame_info *frame = get_selected_frame (_("No frame selected"));
-  CORE_ADDR pc = get_frame_pc (frame);
-  int sel = (int) (uintptr_t) data;
   struct objfile *objfile;
-  const struct stap_probe *pc_probe = NULL;
-  int n_probes;
-
-  /* Note that SEL is biased by 1; SEL==0 means "_marker_argc".  */
-  gdb_assert (sel >= 0 && sel <= 10);
 
   ALL_OBJFILES (objfile)
   {
@@ -402,12 +416,33 @@ compute_marker_arg (struct gdbarch *arch, struct internalvar *ivar,
       {
 	if (probes[i].address == pc)
 	  {
-	    pc_probe = &probes[i];
-	    break;
+	    *objfile_out = objfile;
+	    return &probes[i];
 	  }
       }
   }
 
+  return NULL;
+}
+
+/* This is called to compute the value of one of the $_marker_arg*
+   convenience variables.  */
+
+static struct value *
+compute_marker_arg (struct gdbarch *arch, struct internalvar *ivar,
+		    void *data)
+{
+  struct frame_info *frame = get_selected_frame (_("No frame selected"));
+  CORE_ADDR pc = get_frame_pc (frame);
+  int sel = (int) (uintptr_t) data;
+  struct objfile *objfile;
+  const struct stap_probe *pc_probe;
+  int n_probes;
+
+  /* Note that SEL is biased by 1; SEL==0 means "_marker_argc".  */
+  gdb_assert (sel >= 0 && sel <= 10);
+
+  pc_probe = find_probe_by_pc (pc, &objfile);
   if (pc_probe == NULL)
     error (_("No SystemTap probe at PC %s"), core_addr_to_string (pc));
 
diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h
index 1967e7b..c7d8e7f 100644
--- a/gdb/stap-probe.h
+++ b/gdb/stap-probe.h
@@ -45,4 +45,18 @@ struct stap_probe
 
 extern struct symtabs_and_lines parse_stap_probe (char **argptr);
 
+/* Search OBJFILE for a probe with the given PROVIDER and NAME.  If a
+   probe is found, return it.  If no probe is found, return NULL.  */
+
+extern const struct stap_probe *find_probe_in_objfile (struct objfile *objfile,
+						       const char *provider,
+						       const char *name);
+
+/* Given a PC, find an associated SystemTap probe.  If a probe is
+   found, set *OBJFILE_OUT to the probe's objfile, and return the
+   probe.  If no probe is found, return NULL.  */
+
+extern const struct stap_probe *find_probe_by_pc (CORE_ADDR pc,
+						  struct objfile **objfile_out);
+
 #endif /* !defined (STAP_PROBE_H) */


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-02-10 18:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-10 18:42 [SCM] archer-sergiodj-stap: make exception-related breakpoints use stap probes when available this is untested; it needs the probe arguments to work first tromey

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