* Re: [rfc breakpoint] Catch exceptions
[not found] <1048606641.15061.ezmlm@sources.redhat.com>
@ 2003-03-25 23:51 ` Jim Ingham
2003-03-26 0:03 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Jim Ingham @ 2003-03-25 23:51 UTC (permalink / raw)
To: gdb-patches
One thing we had to worry about at least on Mac OS X is that we don't
use a shared libstdc++, rather every shlib that uses C++ get its own
copy of all the libsupc++ code. So there are actually many copies of
__cxa__begin_catch hanging around. To do this properly, you have to
search exhaustively for these symbols, not just take the first hit.
Moreover, you have to redo it on every shared library load, or you will
miss some. This still might bite you on other systems, for instance if
out of paranoia somebody had linked their shlib or executable
statically to libstdc++.a (so they wouldn't get bit by changing ABI
issues or whatever).
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. I thought I was going to have
time to think about this in the next month or two, but I got
sidetracked on other issues. But I will need to get back to it after
our WWDC (in June).
I thought from some comments in other notes that this was something you
were thinking about as well, Daniel. Is that true?
Jim
On Tuesday, March 25, 2003, at 07:37 AM,
gdb-patches-digest-help@sources.redhat.com wrote:
> +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;
> +}
> +
>
--
Jim Ingham jingham@apple.com
Developer Tools
Apple Computer
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [rfc breakpoint] Catch exceptions
2003-03-25 23:51 ` [rfc breakpoint] Catch exceptions Jim Ingham
@ 2003-03-26 0:03 ` Daniel Jacobowitz
2003-03-26 2:14 ` Jim Ingham
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-03-26 0:03 UTC (permalink / raw)
To: Jim Ingham; +Cc: gdb-patches
On Tue, Mar 25, 2003 at 03:51:32PM -0800, Jim Ingham wrote:
> One thing we had to worry about at least on Mac OS X is that we don't
> use a shared libstdc++, rather every shlib that uses C++ get its own
> copy of all the libsupc++ code. So there are actually many copies of
> __cxa__begin_catch hanging around. To do this properly, you have to
> search exhaustively for these symbols, not just take the first hit.
> Moreover, you have to redo it on every shared library load, or you will
> miss some. This still might bite you on other systems, for instance if
> out of paranoia somebody had linked their shlib or executable
> statically to libstdc++.a (so they wouldn't get bit by changing ABI
> issues or whatever).
>
> 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. I thought I was going to have
> time to think about this in the next month or two, but I got
> sidetracked on other issues. But I will need to get back to it after
> our WWDC (in June).
Yes. Rather than focusing on it with a special hack here, I'd rather
eventually address it properly. Thanks for pointing this out.
> I thought from some comments in other notes that this was something you
> were thinking about as well, Daniel. Is that true?
I'm interested in the problem, but like everyone I have a dreadful
shortage of time :(
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [rfc breakpoint] Catch exceptions
2003-03-26 0:03 ` Daniel Jacobowitz
@ 2003-03-26 2:14 ` Jim Ingham
0 siblings, 0 replies; 11+ messages in thread
From: Jim Ingham @ 2003-03-26 2:14 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Tuesday, March 25, 2003, at 04:03 PM, Daniel Jacobowitz wrote:
> On Tue, Mar 25, 2003 at 03:51:32PM -0800, Jim Ingham wrote:
>> One thing we had to worry about at least on Mac OS X is that we don't
>> use a shared libstdc++, rather every shlib that uses C++ get its own
>> copy of all the libsupc++ code. So there are actually many copies of
>> __cxa__begin_catch hanging around. To do this properly, you have to
>> search exhaustively for these symbols, not just take the first hit.
>> Moreover, you have to redo it on every shared library load, or you
>> will
>> miss some. This still might bite you on other systems, for instance
>> if
>> out of paranoia somebody had linked their shlib or executable
>> statically to libstdc++.a (so they wouldn't get bit by changing ABI
>> issues or whatever).
>>
>> 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. I thought I was going to have
>> time to think about this in the next month or two, but I got
>> sidetracked on other issues. But I will need to get back to it after
>> our WWDC (in June).
>
> Yes. Rather than focusing on it with a special hack here, I'd rather
> eventually address it properly. Thanks for pointing this out.
That seems fine.
>
>> I thought from some comments in other notes that this was something
>> you
>> were thinking about as well, Daniel. Is that true?
>
> I'm interested in the problem, but like everyone I have a dreadful
> shortage of time :(
>
Another complication we should address is that gdb currently tries to
reset all breakpoints in all shared libraries when it does
breakpoint_re_set_all... It would be better if gdb could figure out
which shared libraries have been added on a shlib event, and only reset
in them. This seems trivial, but on Mac OS X (and I bet on a fully
loaded KDE or Gnome system) there are LOTS of shared libraries, and
this is a major speed problem. It is even worse for systems with
shared library based plugins, where you can end up loading ~100 plugins
one by one. Setting ~20 or 30 breakpoints for all the shlibs in the
system plus the increasing list from the plugins, for each load of 100
plugins, really dogs down...
I think I know how to do this on our gdb, but it will take some more
thought to figure out how to do it generically...
Jim
--
Jim Ingham jingham@apple.com
Developer Tools
Apple Computer
^ permalink raw reply [flat|nested] 11+ messages in thread
* 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
* Re: [rfc breakpoint] Catch exceptions
2003-03-26 17:48 Michael Elizabeth Chastain
@ 2003-03-26 22:49 ` Jim Ingham
0 siblings, 0 replies; 11+ messages in thread
From: Jim Ingham @ 2003-03-26 22:49 UTC (permalink / raw)
To: Michael Elizabeth Chastain; +Cc: gdb-patches
Yeah, the Apple gcc folks made it so that all the [in-charge] and
[not-in-charge] etc versions of constructors & destructors funnel back
into a single function, then we just make sure gdb breaks on that one
when it goes to break on the constructor. It looks a little odd,
'cause you have this weirdo extra stack frame that you don't
understand, but at least it works. Dunno if they ever submitted that
hack back to the FSF, however. If they did, the gdb side was pretty
trivial.
Jim
On Wednesday, March 26, 2003, at 09:48 AM, Michael Elizabeth Chastain
wrote:
> 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
>
--
Jim Ingham jingham@apple.com
Developer Tools
Apple Computer
^ permalink raw reply [flat|nested] 11+ messages in thread
* [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* Re: [rfc breakpoint] Catch exceptions
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
1 sibling, 1 reply; 11+ messages in thread
From: Andrew Cagney @ 2003-03-25 16:05 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: 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.
If you're not happy with a design, the best thing to do is toss it on a
branch where it can incubate a little.
> 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:
This is the more interesting bit:
+ enum {ep_normal, ep_gnuv2, ep_gnuv3} ep_type;
You're expecting multiple implementations ...
> + enum print_stop_action (*print) (struct breakpoint *);
> +
> + void (*print_one) (struct breakpoint *, CORE_ADDR *);
> +
> + void (*print_mention) (struct breakpoint *);
Per frame-unwind, instead put these virutal methods in their own struct
and then point the breakpoint at it. Separate v2 and v3 catchpoints (in
separate files?) will then be possible (and make the enum unnecessary).
Long term, the `breakpoint' code should do everything via these virtual
methods. If a breakpoint is hit, the corresponding handler should be
called.
Those methods should rely on zero globals - pass everything in.
Some nits:
Just write this:
+ (*b->print_mention) (b);
like:
b->print_mention (b)
While I know some kernel groups like to use that style, GDB doesn't
appear to.
This, and related, should be submitted separatly:
+extern struct symtab_and_line find_msymbol_start_sal (struct
minimal_symbol *,
+ int);
Any chance of a comment?
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [rfc breakpoint] Catch exceptions
2003-03-25 16:05 ` Andrew Cagney
@ 2003-03-25 16:14 ` Daniel Jacobowitz
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-03-25 16:14 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
On Tue, Mar 25, 2003 at 11:05:11AM -0500, Andrew Cagney wrote:
> >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.
>
> If you're not happy with a design, the best thing to do is toss it on a
> branch where it can incubate a little.
I know from experience that I don't have time to maintain a branch for
something I'm just doing in my spare time; this isn't an important
project.
> >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:
>
> This is the more interesting bit:
>
> + enum {ep_normal, ep_gnuv2, ep_gnuv3} ep_type;
>
> You're expecting multiple implementations ...
That should actually be replaced with something opaque. Meant to fix
that, oops.
They'll be mostly the same, but the code for conditional stops will be
different.
> >+ enum print_stop_action (*print) (struct breakpoint *);
> >+
> >+ void (*print_one) (struct breakpoint *, CORE_ADDR *);
> >+
> >+ void (*print_mention) (struct breakpoint *);
>
> Per frame-unwind, instead put these virutal methods in their own struct
> and then point the breakpoint at it. Separate v2 and v3 catchpoints (in
> separate files?) will then be possible (and make the enum unnecessary).
OK, good idea. Separate files is possible but seems unlikely to
happen.
> Long term, the `breakpoint' code should do everything via these virtual
> methods. If a breakpoint is hit, the corresponding handler should be
> called.
Yes, that's my hope. Practical? Maybe.
> Those methods should rely on zero globals - pass everything in.
I think that's the case, I'll recheck.
> Some nits:
>
> Just write this:
> + (*b->print_mention) (b);
> like:
> b->print_mention (b)
> While I know some kernel groups like to use that style, GDB doesn't
> appear to.
OK; I prefer the former style but it doesn't really matter.
> This, and related, should be submitted separatly:
> +extern struct symtab_and_line find_msymbol_start_sal (struct
> minimal_symbol *,
> + int);
>
> Any chance of a comment?
Sure.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [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
2003-05-02 0:13 ` David Carlton
1 sibling, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-04-27 17:52 UTC (permalink / raw)
To: gdb-patches
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
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [rfc breakpoint] Catch exceptions
2003-04-27 17:52 ` Daniel Jacobowitz
@ 2003-05-02 0:13 ` David Carlton
2003-05-02 0:25 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: David Carlton @ 2003-05-02 0:13 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Sat, 26 Apr 2003 21:13:07 -0400, Daniel Jacobowitz <drow@mvista.com> said:
> On Mon, Mar 24, 2003 at 10:01:07PM -0500, Daniel Jacobowitz wrote:
>> The feature being implemented here is "catch catch" and "catch
>> throw".
> The patch I checked in is the below, plus some reindentation where I
> moved two switch statements into else clauses.
Could you add some testsuite cases for this when you have time?
Thanks,
David Carlton
carlton@math.stanford.edu
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [rfc breakpoint] Catch exceptions
2003-05-02 0:13 ` David Carlton
@ 2003-05-02 0:25 ` Daniel Jacobowitz
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-05-02 0:25 UTC (permalink / raw)
To: David Carlton; +Cc: gdb-patches
On Thu, May 01, 2003 at 05:13:20PM -0700, David Carlton wrote:
> On Sat, 26 Apr 2003 21:13:07 -0400, Daniel Jacobowitz <drow@mvista.com> said:
> > On Mon, Mar 24, 2003 at 10:01:07PM -0500, Daniel Jacobowitz wrote:
>
> >> The feature being implemented here is "catch catch" and "catch
> >> throw".
>
> > The patch I checked in is the below, plus some reindentation where I
> > moved two switch statements into else clauses.
>
> Could you add some testsuite cases for this when you have time?
Yeah, I need to. There are a lot in gdb.hp, but recovering them into
something usable may be almost impossible. Hopefully I'll prettify the
interface a little before then...
It's on The List.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ 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 --
[not found] <1048606641.15061.ezmlm@sources.redhat.com>
2003-03-25 23:51 ` [rfc breakpoint] Catch exceptions 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
-- 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