Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re:  [rfc breakpoint] Catch exceptions
@ 2003-03-26 17:48 Michael Elizabeth Chastain
  2003-03-26 22:49 ` Jim Ingham
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Elizabeth Chastain @ 2003-03-26 17:48 UTC (permalink / raw)
  To: gdb-patches, jingham

Hi Jim,

> BTW. The more general problem of a symbol resolving to multiple 
> instances - for instance setting file:line breakpoints in inlined 
> functions or template method defn's - is something we need to address.  
> It really ticks off our C++ friends.

And with gcc 3, it happens with constructors and destructors, because
the compiler emits multiple object code functions for each constructor
and each constructor.  This shows up multiple times in the PR database,
which means many users are unhappy with it.

Just another voice of gloom,

Michael C


^ permalink raw reply	[flat|nested] 11+ messages in thread
[parent not found: <1048606641.15061.ezmlm@sources.redhat.com>]
* [rfc breakpoint] Catch exceptions
@ 2003-03-25  3:01 Daniel Jacobowitz
  2003-03-25 16:05 ` Andrew Cagney
  2003-04-27 17:52 ` Daniel Jacobowitz
  0 siblings, 2 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-03-25  3:01 UTC (permalink / raw)
  To: gdb-patches

I'm just looking for feedback on this patch.  It's mostly complete except
for some mass re-indenting that some of the changes would require; I'm not
entirely happy with the design yet though, so I'm looking for comments.

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.

The basic idea is that these "catchpoints" are just normal breakpoints and
should be handled as such.  But we'd like to print them a little
differently, for clarity.

Here's the interesting bit, from struct breakpoint:
+    enum print_stop_action (*print) (struct breakpoint *);
+
+    void (*print_one) (struct breakpoint *, CORE_ADDR *);
+
+    void (*print_mention) (struct breakpoint *);

i.e. it adds function pointers to the breakpoint to describe the action to
take.  Logical next steps include a function to determine whether to stop
(for catch throw TYPE) and maybe even a function to take action when hit (to
simplify longjmp and step_resume breakpoints, etc. - breakpoint.c could be
simplified by this mechanism long-term).

[Why three subtly different print functions?  Because there were three
places I needed a hook and they were all different.  This sucks.  At least
two of them can be condensed... I think... eventually.  I'm not interested
in doing that level of cleanup right now, particularly.]

Comments?  If no one has any, I'll look to commit this (with reformatting)
in a while.  Maybe a week or so.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

Index: breakpoint.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/breakpoint.c,v
retrieving revision 1.114
diff -u -p -r1.114 breakpoint.c
--- breakpoint.c	11 Mar 2003 19:07:01 -0000	1.114
+++ breakpoint.c	25 Mar 2003 02:49:23 -0000
@@ -2017,6 +2013,9 @@ print_it_typical (bpstat bs)
   if (bs->breakpoint_at == NULL)
     return PRINT_UNKNOWN;
 
+  if (bs->breakpoint_at->print != NULL)
+    return (*bs->breakpoint_at->print) (bs->breakpoint_at);
+
   switch (bs->breakpoint_at->type)
     {
     case bp_breakpoint:
@@ -3272,7 +3271,10 @@ print_one_breakpoint (struct breakpoint 
       else
 	strcat (wrap_indent, "                   ");
     }
-  switch (b->type)
+
+  if (b->print_one != NULL)
+    (*b->print_one) (b, last_addr);
+  else switch (b->type)
     {
     case bp_none:
       internal_error (__FILE__, __LINE__,
@@ -4420,7 +4423,9 @@ mention (struct breakpoint *b)
     create_breakpoint_hook (b);
   breakpoint_create_event (b->number);
 
-  switch (b->type)
+  if (b->print_mention != NULL)
+    (*b->print_mention) (b);
+  else switch (b->type)
     {
     case bp_none:
       printf_filtered ("(apparently deleted?) Eventpoint %d: ", b->number);
@@ -6192,6 +6016,84 @@ 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 int
+handle_gnu_v3_exceptions (int tempflag, char *cond_string,
+			  enum exception_event_kind ex_event, int from_tty)
+{
+  struct minimal_symbol *trigger_func;
+  const char *trigger_func_name;
+  struct symtab_and_line sal;
+  struct breakpoint *b;
+
+  if (ex_event == EX_EVENT_CATCH)
+    trigger_func_name = "__cxa_begin_catch";
+  else
+    trigger_func_name = "__cxa_throw";
+
+  trigger_func = lookup_minimal_symbol (trigger_func_name, NULL, NULL);
+  if (trigger_func == 0)
+    return 0;
+  sal = find_msymbol_start_sal (trigger_func, 1);
+
+  b = set_raw_breakpoint (sal, 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 = xstrdup (trigger_func_name);
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
+  mention (b);
+  b->ep_type = ep_gnuv3;
+
+  b->print = print_exception_catchpoint;
+  b->print_one = print_one_exception_catchpoint;
+  b->print_mention = print_mention_exception_catchpoint;
+  return 1;
+}
+
 /* Deal with "catch catch" and "catch throw" commands */
 
 static void
@@ -6212,6 +6114,9 @@ catch_exception_command_1 (enum exceptio
       (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.19
diff -u -p -r1.19 breakpoint.h
--- breakpoint.h	20 Feb 2003 00:01:05 -0000	1.19
+++ breakpoint.h	25 Mar 2003 02:46:57 -0000
@@ -305,6 +305,14 @@ struct breakpoint
        triggered.  */
     char *exec_pathname;
 
+    enum {ep_normal, ep_gnuv2, ep_gnuv3} ep_type;
+
+    enum print_stop_action (*print) (struct breakpoint *);
+
+    void (*print_one) (struct breakpoint *, CORE_ADDR *);
+
+    void (*print_mention) (struct breakpoint *);
+
     asection *section;
   };
 \f
Index: linespec.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/linespec.c,v
retrieving revision 1.45
diff -u -p -r1.45 linespec.c
--- linespec.c	3 Mar 2003 17:20:24 -0000	1.45
+++ linespec.c	17 Mar 2003 17:06:34 -0000
@@ -1543,14 +1543,7 @@ minsym_found (int funfirstline, struct m
 
   values.sals = (struct symtab_and_line *)
     xmalloc (sizeof (struct symtab_and_line));
-  values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
-				      (struct sec *) 0, 0);
-  values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
-  if (funfirstline)
-    {
-      values.sals[0].pc += FUNCTION_START_OFFSET;
-      values.sals[0].pc = SKIP_PROLOGUE (values.sals[0].pc);
-    }
+  values.sals[0] = find_msymbol_start_sal (msymbol, funfirstline);
   values.nelts = 1;
   return values;
 }
Index: symtab.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symtab.c,v
retrieving revision 1.99
diff -u -p -r1.99 symtab.c
--- symtab.c	4 Mar 2003 17:06:21 -0000	1.99
+++ symtab.c	17 Mar 2003 17:08:01 -0000
@@ -2462,6 +2462,27 @@ find_function_start_sal (struct symbol *
   return sal;
 }
 
+/* Given a minimal symbol MSYMBOL, build a corresponding struct
+   symtabs_and_lines.
+   If the argument FUNFIRSTLINE is nonzero, we want the first line
+   of real code inside the function, so skip the prologue.  */
+
+struct symtab_and_line
+find_msymbol_start_sal (struct minimal_symbol *msymbol, int funfirstline)
+{
+  struct symtab_and_line sal;
+
+  sal = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
+			   (struct sec *) 0, 0);
+  sal.section = SYMBOL_BFD_SECTION (msymbol);
+  if (funfirstline)
+    {
+      sal.pc += FUNCTION_START_OFFSET;
+      sal.pc = SKIP_PROLOGUE (sal.pc);
+    }
+  return sal;
+}
+
 /* If P is of the form "operator[ \t]+..." where `...' is
    some legitimate operator text, return a pointer to the
    beginning of the substring of the operator text.
Index: symtab.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symtab.h,v
retrieving revision 1.65
diff -u -p -r1.65 symtab.h
--- symtab.h	3 Mar 2003 18:34:12 -0000	1.65
+++ symtab.h	17 Mar 2003 17:07:03 -0000
@@ -1272,6 +1272,9 @@ extern struct symtab *find_line_symtab (
 extern struct symtab_and_line find_function_start_sal (struct symbol *sym,
 						       int);
 
+extern struct symtab_and_line find_msymbol_start_sal (struct minimal_symbol *,
+						      int);
+
 /* symfile.c */
 
 extern void clear_symtab_users (void);


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2003-05-02  0:25 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-26 17:48 [rfc breakpoint] Catch exceptions Michael Elizabeth Chastain
2003-03-26 22:49 ` Jim Ingham
     [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
  -- strict thread matches above, loose matches on Subject: below --
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
2003-05-02  0:13   ` David Carlton
2003-05-02  0:25     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox