Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Daniel Jacobowitz <drow@mvista.com>
To: gdb-patches@sources.redhat.com
Subject: Re: [rfc breakpoint] Catch exceptions
Date: Sun, 27 Apr 2003 17:52:00 -0000	[thread overview]
Message-ID: <20030427011306.GA4437@nevyn.them.org> (raw)
In-Reply-To: <20030325030107.GA3889@nevyn.them.org>

On Mon, Mar 24, 2003 at 10:01:07PM -0500, Daniel Jacobowitz wrote:
> The feature being implemented here is "catch catch" and "catch throw".  This
> patch just does gcc v3; gcc v2.95 is easy to add afterwards, and I also have
> a patch to remove the ancient GNU support for this feature for some 1.x g++
> versions (or maybe early 2.x?).  HP, as usual, supports this in a completely
> different way.

Updated version (simplified) is below.  It looks much nicer now.  The
support is rudimentary, but good enough to be quite useful, I think.

The patch I checked in is the below, plus some reindentation where I
moved two switch statements into else clauses.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-04-26  Daniel Jacobowitz  <drow@mvista.com>

	* breakpoint.h (struct breakpoint_ops): New.
	(struct breakpoint): Add ops member.

	* breakpoint.c (print_bp_stop_message, print_one_breakpoint)
	(mention): Use new breakpoint ops member.
	(set_raw_breakpoint): Initialize ops field to NULL.
	(print_exception_catchpoint, print_one_exception_catchpoint)
	(print_mention_exception_catchpoint, handle_gnu_v3_exceptions): New.
	(gnu_v3_exception_catchpoint_ops): New.
	(catch_exception_command_1): Call handle_gnu_v3_exceptions.

Index: breakpoint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/breakpoint.c,v
retrieving revision 1.118
diff -u -p -b -B -w -r1.118 breakpoint.c
--- breakpoint.c	10 Apr 2003 03:30:36 -0000	1.118
+++ breakpoint.c	27 Apr 2003 00:58:11 -0000
@@ -2271,9 +2271,15 @@ print_bp_stop_message (bpstat bs)
       break;
 
     case print_it_normal:
-      /* Normal case, we handle everything in print_it_typical. */
+      /* Normal case.  Call the breakpoint's print_it method, or
+	 print_it_typical.  */
+      if (bs->breakpoint_at != NULL && bs->breakpoint_at->ops != NULL
+	  && bs->breakpoint_at->ops->print_it != NULL)
+	return bs->breakpoint_at->ops->print_it (bs->breakpoint_at);
+      else
       return print_it_typical (bs);
       break;
+
     default:
       internal_error (__FILE__, __LINE__,
 		      "print_bp_stop_message: unrecognized enum value");
@@ -3265,6 +3271,10 @@ print_one_breakpoint (struct breakpoint 
       else
 	strcat (wrap_indent, "                   ");
     }
+
+  if (b->ops != NULL && b->ops->print_one != NULL)
+    b->ops->print_one (b, last_addr);
+  else
   switch (b->type)
     {
     case bp_none:
@@ -3851,6 +3861,7 @@ set_raw_breakpoint (struct symtab_and_li
   b->triggered_dll_pathname = NULL;
   b->forked_inferior_pid = 0;
   b->exec_pathname = NULL;
+  b->ops = NULL;
 
   /* Add this breakpoint to the end of the chain
      so that a list of breakpoints will come out in order
@@ -4413,6 +4424,9 @@ mention (struct breakpoint *b)
     create_breakpoint_hook (b);
   breakpoint_create_event (b->number);
 
+  if (b->ops != NULL && b->ops->print_mention != NULL)
+    b->ops->print_mention (b);
+  else
   switch (b->type)
     {
     case bp_none:
@@ -6004,6 +6019,90 @@ create_exception_catchpoint (int tempfla
   mention (b);
 }
 
+static enum print_stop_action
+print_exception_catchpoint (struct breakpoint *b)
+{
+  annotate_catchpoint (b->number);
+
+  if (strstr (b->addr_string, "throw") != NULL)
+    printf_filtered ("\nCatchpoint %d (exception thrown)\n",
+		     b->number);
+  else
+    printf_filtered ("\nCatchpoint %d (exception caught)\n",
+		     b->number);
+
+  return PRINT_SRC_AND_LOC;
+}
+
+static void
+print_one_exception_catchpoint (struct breakpoint *b, CORE_ADDR *last_addr)
+{
+  if (addressprint)
+    {
+      annotate_field (4);
+      ui_out_field_core_addr (uiout, "addr", b->address);
+    }
+  annotate_field (5);
+  *last_addr = b->address;
+  if (strstr (b->addr_string, "throw") != NULL)
+    ui_out_field_string (uiout, "what", "exception throw");
+  else
+    ui_out_field_string (uiout, "what", "exception catch");
+}
+
+static void
+print_mention_exception_catchpoint (struct breakpoint *b)
+{
+  if (strstr (b->addr_string, "throw") != NULL)
+    printf_filtered ("Catchpoint %d (throw)", b->number);
+  else
+    printf_filtered ("Catchpoint %d (catch)", b->number);
+}
+
+static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
+  print_exception_catchpoint,
+  print_one_exception_catchpoint,
+  print_mention_exception_catchpoint
+};
+
+static int
+handle_gnu_v3_exceptions (int tempflag, char *cond_string,
+			  enum exception_event_kind ex_event, int from_tty)
+{
+  char *trigger_func_name, *nameptr;
+  struct symtabs_and_lines sals;
+  struct breakpoint *b;
+
+  if (ex_event == EX_EVENT_CATCH)
+    trigger_func_name = xstrdup ("__cxa_begin_catch");
+  else
+    trigger_func_name = xstrdup ("__cxa_throw");
+
+  nameptr = trigger_func_name;
+  sals = decode_line_1 (&nameptr, 1, NULL, 0, NULL);
+  if (sals.nelts == 0)
+    {
+      free (trigger_func_name);
+      return 0;
+    }
+
+  b = set_raw_breakpoint (sals.sals[0], bp_breakpoint);
+  set_breakpoint_count (breakpoint_count + 1);
+  b->number = breakpoint_count;
+  b->cond = NULL;
+  b->cond_string = (cond_string == NULL) ? 
+    NULL : savestring (cond_string, strlen (cond_string));
+  b->thread = -1;
+  b->addr_string = trigger_func_name;
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
+  b->ops = &gnu_v3_exception_catchpoint_ops;
+
+  free (sals.sals);
+  mention (b);
+  return 1;
+}
+
 /* Deal with "catch catch" and "catch throw" commands */
 
 static void
@@ -6023,6 +6122,9 @@ catch_exception_command_1 (enum exceptio
   if ((ex_event != EX_EVENT_THROW) &&
       (ex_event != EX_EVENT_CATCH))
     error ("Unsupported or unknown exception event; cannot catch it");
+
+  if (handle_gnu_v3_exceptions (tempflag, cond_string, ex_event, from_tty))
+    return;
 
   /* See if we can find a callback routine */
   sal = target_enable_exception_callback (ex_event, 1);
Index: breakpoint.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/breakpoint.h,v
retrieving revision 1.20
diff -u -p -b -B -w -r1.20 breakpoint.h
--- breakpoint.h	21 Apr 2003 16:48:37 -0000	1.20
+++ breakpoint.h	27 Apr 2003 00:20:28 -0000
@@ -184,6 +184,24 @@ enum target_hw_bp_type
     hw_execute = 3		/* Execute HW breakpoint */
   };
 
+/* This structure is a collection of function pointers that, if available,
+   will be called instead of the performing the default action for this
+   bptype.  */
+
+struct breakpoint_ops 
+{
+  /* The normal print routine for this breakpoint, called when we
+     hit it.  */
+  enum print_stop_action (*print_it) (struct breakpoint *);
+
+  /* Display information about this breakpoint, for "info breakpoints".  */
+  void (*print_one) (struct breakpoint *, CORE_ADDR *);
+
+  /* Display information about this breakpoint after setting it (roughly
+     speaking; this is called from "mention").  */
+  void (*print_mention) (struct breakpoint *);
+};
+
 /* Note that the ->silent field is not currently used by any commands
    (though the code is in there if it was to be, and set_raw_breakpoint
    does set it to 0).  I implemented it because I thought it would be
@@ -306,6 +324,9 @@ struct breakpoint
     char *exec_pathname;
 
     asection *section;
+
+    /* Methods associated with this breakpoint.  */
+    struct breakpoint_ops *ops;
   };
 \f
 /* The following stuff is an abstract data type "bpstat" ("breakpoint


  parent reply	other threads:[~2003-04-27  1:13 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-03-25  3:01 Daniel Jacobowitz
2003-03-25 16:05 ` Andrew Cagney
2003-03-25 16:14   ` Daniel Jacobowitz
2003-04-27 17:52 ` Daniel Jacobowitz [this message]
2003-05-02  0:13   ` David Carlton
2003-05-02  0:25     ` Daniel Jacobowitz
     [not found] <1048606641.15061.ezmlm@sources.redhat.com>
2003-03-25 23:51 ` Jim Ingham
2003-03-26  0:03   ` Daniel Jacobowitz
2003-03-26  2:14     ` Jim Ingham
2003-03-26 17:48 Michael Elizabeth Chastain
2003-03-26 22:49 ` Jim Ingham

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=20030427011306.GA4437@nevyn.them.org \
    --to=drow@mvista.com \
    --cc=gdb-patches@sources.redhat.com \
    /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