Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Sergio Durigan Junior <sergiodj@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 3/4 v3] Use longjmp and exception probes when available
Date: Mon, 23 Apr 2012 04:59:00 -0000	[thread overview]
Message-ID: <m3fwbvujqq.fsf@redhat.com> (raw)
In-Reply-To: <m3sjfvuk08.fsf@redhat.com> (Sergio Durigan Junior's message of	"Mon, 23 Apr 2012 01:53:11 -0300")

Hi,

This patch also almost didn't change from the first version.

    http://sourceware.org/ml/gdb-patches/2012-03/msg00356.html

OK to check-in?

2012-04-23  Sergio Durigan Junior  <sergiodj@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* breakpoint.c (struct breakpoint_objfile_data)
	<longjmp_searched>,<longjmp_probes>,<exception_searched>,
	<exception_probes>: New fields.
	(free_breakpoint_probes): New function.
	(create_longjmp_master_breakpoint): Prefer SystemTap probe over
	`_Unwind_DebugHook'.
	(create_exception_master_breakpoint): Likewise.
	(_initialize_breakpoint): Registering cleanup for SystemTap probes.
	* infrun.c: Including necessary header files for handling SystemTap
	probes.
	(handle_inferior_event): Handling longjmp breakpoint and exceptions
	via SystemTap probes.
	(check_exception_resume): Remove `func' argument.  Handle exception
	unwinding breakpoint set via a SystemTap probe.
	(insert_exception_resume_from_probe): New function.

---
 gdb/breakpoint.c |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/infrun.c     |   77 +++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 152 insertions(+), 11 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index ce0ee62..1d719e4 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2733,11 +2733,23 @@ struct breakpoint_objfile_data
   /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any).  */
   struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
 
+  /* True if we have looked for longjmp probes.  */
+  int longjmp_searched;
+
+  /* SystemTap probe points for longjmp (if any).  */
+  VEC (probe_p) *longjmp_probes;
+
   /* Minimal symbol for "std::terminate()" (if any).  */
   struct minimal_symbol *terminate_msym;
 
   /* Minimal symbol for "_Unwind_DebugHook" (if any).  */
   struct minimal_symbol *exception_msym;
+
+  /* True if we have looked for exception probes.  */
+  int exception_searched;
+
+  /* SystemTap probe points for unwinding (if any).  */
+  VEC (probe_p) *exception_probes;
 };
 
 static const struct objfile_data *breakpoint_objfile_key;
@@ -2774,6 +2786,15 @@ get_breakpoint_objfile_data (struct objfile *objfile)
 }
 
 static void
+free_breakpoint_probes (struct objfile *obj, void *data)
+{
+  struct breakpoint_objfile_data *bp_objfile_data = data;
+
+  VEC_free (probe_p, bp_objfile_data->longjmp_probes);
+  VEC_free (probe_p, bp_objfile_data->exception_probes);
+}
+
+static void
 create_overlay_event_breakpoint (void)
 {
   struct objfile *objfile;
@@ -2850,6 +2871,37 @@ create_longjmp_master_breakpoint (void)
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
+      if (!bp_objfile_data->longjmp_searched)
+	{
+	  bp_objfile_data->longjmp_probes
+	    = find_probes_in_objfile (objfile, "libc", "longjmp");
+	  bp_objfile_data->longjmp_searched = 1;
+	}
+
+      if (bp_objfile_data->longjmp_probes != NULL)
+	{
+	  int i;
+	  struct probe *probe;
+	  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+	  for (i = 0;
+	       VEC_iterate (probe_p,
+			    bp_objfile_data->longjmp_probes,
+			    i, probe);
+	       ++i)
+	    {
+	      struct breakpoint *b;
+
+	      b = create_internal_breakpoint (gdbarch, probe->address,
+					      bp_longjmp_master,
+					      &internal_breakpoint_ops);
+	      b->addr_string = xstrdup ("-probe-stap libc:longjmp");
+	      b->enable_state = bp_disabled;
+	    }
+
+	  continue;
+	}
+
       for (i = 0; i < NUM_LONGJMP_NAMES; i++)
 	{
 	  struct breakpoint *b;
@@ -2960,6 +3012,40 @@ create_exception_master_breakpoint (void)
 
       bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
+      /* We prefer the SystemTap probe point if it exists.  */
+      if (!bp_objfile_data->exception_searched)
+	{
+	  bp_objfile_data->exception_probes
+	    = find_probes_in_objfile (objfile, "libgcc", "unwind");
+	  bp_objfile_data->exception_searched = 1;
+	}
+
+      if (bp_objfile_data->exception_probes != NULL)
+	{
+	  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+	  int i;
+	  struct probe *probe;
+
+	  for (i = 0;
+	       VEC_iterate (probe_p,
+			    bp_objfile_data->exception_probes,
+			    i, probe);
+	       ++i)
+	    {
+	      struct breakpoint *b;
+
+	      b = create_internal_breakpoint (gdbarch, probe->address,
+					      bp_exception_master,
+					      &internal_breakpoint_ops);
+	      b->addr_string = xstrdup ("-probe-stap libgcc:unwind");
+	      b->enable_state = bp_disabled;
+	    }
+
+	  continue;
+	}
+
+      /* Otherwise, try the hook function.  */
+
       if (msym_not_found_p (bp_objfile_data->exception_msym))
 	continue;
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index c8a697a..e779c2a 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -55,6 +55,8 @@
 #include "continuations.h"
 #include "interps.h"
 #include "skip.h"
+#include "probe.h"
+#include "objfiles.h"
 
 /* Prototypes for local functions */
 
@@ -2402,7 +2404,7 @@ static void handle_step_into_function (struct gdbarch *gdbarch,
 static void handle_step_into_function_backward (struct gdbarch *gdbarch,
 						struct execution_control_state *ecs);
 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);
@@ -4437,9 +4439,17 @@ process_event_stop_test:
 
 	if (what.is_longjmp)
 	  {
-	    if (!gdbarch_get_longjmp_target_p (gdbarch)
-		|| !gdbarch_get_longjmp_target (gdbarch,
-						frame, &jmp_buf_pc))
+	    struct value *arg_value;
+
+	    /* If we set the longjmp breakpoint via a SystemTap probe,
+	       then use it to extract the arguments.  The destination
+	       PC is the third argument to the probe.  */
+	    arg_value = probe_safe_evaluate_at_pc (frame, 2);
+	    if (arg_value)
+	      jmp_buf_pc = value_as_address (arg_value);
+	    else if (!gdbarch_get_longjmp_target_p (gdbarch)
+		     || !gdbarch_get_longjmp_target (gdbarch,
+						     frame, &jmp_buf_pc))
 	      {
 		if (debug_infrun)
 		  fprintf_unfiltered (gdb_stdlog,
@@ -4457,12 +4467,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;
 
@@ -5549,15 +5554,65 @@ 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 probe *probe,
+				    struct objfile *objfile,
+				    struct frame_info *frame)
+{
+  struct value *arg_value;
+  CORE_ADDR handler;
+  struct breakpoint *bp;
+
+  arg_value = probe_safe_evaluate_at_pc (frame, 1);
+  if (!arg_value)
+    return;
+
+  handler = value_as_address (arg_value);
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+			"infrun: exception resume at %s\n",
+			paddress (get_objfile_arch (objfile),
+				  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)
 {
   volatile struct gdb_exception e;
+  struct objfile *objfile;
+  const struct 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)
     {
-- 
1.7.7.6

-- 
Sergio


  parent reply	other threads:[~2012-04-23  4:59 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-23  4:57 [PATCH 0/4 v3] Add support for static and SystemTap probes Sergio Durigan Junior
2012-04-23  4:59 ` [PATCH 1/4 v3] Refactor internal variable mechanism Sergio Durigan Junior
2012-04-27 15:40   ` Tom Tromey
2012-04-27 20:57     ` Sergio Durigan Junior
2012-04-23  4:59 ` Sergio Durigan Junior [this message]
2012-04-27 19:47   ` [PATCH 3/4 v3] Use longjmp and exception probes when available Tom Tromey
2012-04-27 20:58     ` Sergio Durigan Junior
2012-04-23  4:59 ` [PATCH 2/4 v3] Implement support for static and SystemTap probes Sergio Durigan Junior
2012-04-27 19:43   ` Tom Tromey
2012-04-27 20:58     ` Sergio Durigan Junior
2012-04-23  6:35 ` [PATCH 4/4 v3] Documentation and testsuite changes Sergio Durigan Junior
2012-04-27 19:58   ` Tom Tromey
2012-04-27 20:32     ` Tom Tromey
2012-04-27 20:57       ` Sergio Durigan Junior
2012-04-28  1:55       ` Sergio Durigan Junior
2012-04-28 23:30 ` Regression for gdb.trace/backtrace.exp [Re: [PATCH 0/4 v3] Add support for static and SystemTap probes] Jan Kratochvil
2012-04-29  6:29   ` Sergio Durigan Junior
2012-04-29 12:59     ` Jan Kratochvil
2012-04-29 18:03       ` Sergio Durigan Junior

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=m3fwbvujqq.fsf@redhat.com \
    --to=sergiodj@redhat.com \
    --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