2011-06-22 Pedro Alves <pedro@codesourcery.com>

* breakpoint.c (bpstat_stop_status): Call the check_status
	breakpoint_ops method.
	(print_one_breakpoint_location): Also print the condition for Ada
	exception catchpoints.
	(allocate_bp_location): New, factored out from
	allocate_bp_location.
	(allocate_bp_location): Adjust.  Call the owner breakpoint's
	allocate_location method, if there is one.
	(free_bp_location): Call the locations's dtor method, if there is
	one.
	(init_raw_breakpoint_without_location): New breakpoint_ops
	parameter.  Use it.
	(set_raw_breakpoint_without_location): Adjust.
	(init_raw_breakpoint): New breakpoint_ops parameter.  Pass it down.
	(set_raw_breakpoint): Adjust.
	(catch_fork_breakpoint_ops, catch_vfork_breakpoint_ops)
	(catch_syscall_breakpoint_ops): Install NULL allocate_location,
	re_set and check_status methods.
	(init_catchpoint): Don't memset, initialize thread, addr_string
	and enable_state.  Pass the ops down to init_raw_breakpoint.
	(install_catchpoint): Rename to ...
	(install_breakpoint): ... this, and make extern.
	(create_fork_vfork_event_catchpoint): Adjust.
	(catch_exec_breakpoint_ops): Install NULL allocate_location,
	re_set and check_status methods.
	(create_syscall_event_catchpoint): Adjust.
	(ranged_breakpoint_ops, watchpoint_breakpoint_ops)
	(masked_watchpoint_breakpoint_ops): Install NULL
	allocate_location, re_set and check_status methods.
	(catch_exec_command_1): Adjust.
	(gnu_v3_exception_catchpoint_ops): Install NULL allocate_location,
	re_set and check_status methods.
	(create_ada_exception_breakpoint): Rename to ...
	(init_ada_exception_breakpoint): ... this.  Add a struct
	breakpoint parameter, and delete the exp_string, cond_string and
	cond parameters.  Use init_raw_breakpoint, and don't install or
	mention the breakpoint yet.  Don't clear breakpoint fields that
	init_raw_breakpoint already clears.
	(re_set_breakpoint): Delete, split into ...
	(breakpoint_re_set_default, prepare_re_set_context): ... these new
	functions.
	(breakpoint_re_set_one): Call the breakpoint's
	breakpoint_ops->re_set implementation, if there's one.  Adjust.
	* breakpoint.h: Forward declare struct bpstats and struct bp_location.
	(struct bp_location_ops): New type.
	(struct bp_location): New field `ops'.
	(struct breakpoint_ops): New `allocate_location', `re_set' and
	`check_status' fields.  Make `breakpoint_hit''s description match
	reality.
	(init_bp_location): Declare.
	(breakpoint_re_set_default): Declare.
	(create_ada_exception_breakpoint): Rename to ...
	(init_ada_exception_breakpoint): ... this.  Add a struct
	breakpoint parameter, and delete the exp_string, cond_string and
	cond parameters.
	(install_breakpoint): Declare.
	* ada-lang.c: Include exceptions.h.
	<Ada exceptions description>: Update.
	(struct ada_catchpoint_location): New type.
	(ada_catchpoint_location_dtor): New function.
	(ada_catchpoint_location_ops): New global.
	(ada_catchpoint): New type.
	(create_excep_cond_exprs): New function.
	(dtor_exception, allocate_location_exception, re_set_exception)
	(should_stop_exception, check_status_exception): New functions.
	(print_one_exception, print_mention_exception)
	(print_recreate_exception): Adjust.
	(dtor_catch_exception, allocate_location_catch_exception)
	(re_set_catch_exception, check_status_catch_exception): New
	functions.
	(catch_exception_breakpoint_ops): Install them.
	(dtor_catch_exception_unhandled)
	(allocate_location_catch_exception_unhandled)
	(re_set_catch_exception_unhandled)
	(check_status_catch_exception_unhandled): New functions.
	(catch_exception_unhandled_breakpoint_ops): Install them.
	(dtor_catch_assert, allocate_location_catch_assert)
	(re_set_catch_assert, check_status_catch_assert): New functions.
	(catch_assert_breakpoint_ops): Install them.
	(ada_exception_catchpoint_p): Delete.
	(catch_ada_exception_command_split)
	(ada_exception_catchpoint_cond_string): Rename exp_string
	parameter to excep_string.  Adjust.
	(ada_parse_catchpoint_condition): Delete.
	(ada_exception_sal): Rename the exp_string parameter to
	excep_string.  Delete the cond_string and cond parameters.
	Adjust.
	(ada_decode_exception_location): Rename the exp_string parameter
	to excep_string.  Delete the cond_string and cond parameters.
	Adjust.
	(create_ada_exception_catchpoint): New function.
	(catch_ada_exception_command, ada_decode_assert_location)
	(catch_assert_command): Adjust.
	* ada-lang.h (ada_exception_catchpoint_p): Delete declaration.
This commit is contained in:
Pedro Alves 2011-06-22 17:53:44 +00:00
parent 9ac4176b6d
commit 28010a5d42
5 changed files with 621 additions and 192 deletions

View File

@ -1,3 +1,100 @@
2011-06-22 Pedro Alves <pedro@codesourcery.com>
* breakpoint.c (bpstat_stop_status): Call the check_status
breakpoint_ops method.
(print_one_breakpoint_location): Also print the condition for Ada
exception catchpoints.
(allocate_bp_location): New, factored out from
allocate_bp_location.
(allocate_bp_location): Adjust. Call the owner breakpoint's
allocate_location method, if there is one.
(free_bp_location): Call the locations's dtor method, if there is
one.
(init_raw_breakpoint_without_location): New breakpoint_ops
parameter. Use it.
(set_raw_breakpoint_without_location): Adjust.
(init_raw_breakpoint): New breakpoint_ops parameter. Pass it down.
(set_raw_breakpoint): Adjust.
(catch_fork_breakpoint_ops, catch_vfork_breakpoint_ops)
(catch_syscall_breakpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(init_catchpoint): Don't memset, initialize thread, addr_string
and enable_state. Pass the ops down to init_raw_breakpoint.
(install_catchpoint): Rename to ...
(install_breakpoint): ... this, and make extern.
(create_fork_vfork_event_catchpoint): Adjust.
(catch_exec_breakpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(create_syscall_event_catchpoint): Adjust.
(ranged_breakpoint_ops, watchpoint_breakpoint_ops)
(masked_watchpoint_breakpoint_ops): Install NULL
allocate_location, re_set and check_status methods.
(catch_exec_command_1): Adjust.
(gnu_v3_exception_catchpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(create_ada_exception_breakpoint): Rename to ...
(init_ada_exception_breakpoint): ... this. Add a struct
breakpoint parameter, and delete the exp_string, cond_string and
cond parameters. Use init_raw_breakpoint, and don't install or
mention the breakpoint yet. Don't clear breakpoint fields that
init_raw_breakpoint already clears.
(re_set_breakpoint): Delete, split into ...
(breakpoint_re_set_default, prepare_re_set_context): ... these new
functions.
(breakpoint_re_set_one): Call the breakpoint's
breakpoint_ops->re_set implementation, if there's one. Adjust.
* breakpoint.h: Forward declare struct bpstats and struct bp_location.
(struct bp_location_ops): New type.
(struct bp_location): New field `ops'.
(struct breakpoint_ops): New `allocate_location', `re_set' and
`check_status' fields. Make `breakpoint_hit''s description match
reality.
(init_bp_location): Declare.
(breakpoint_re_set_default): Declare.
(create_ada_exception_breakpoint): Rename to ...
(init_ada_exception_breakpoint): ... this. Add a struct
breakpoint parameter, and delete the exp_string, cond_string and
cond parameters.
(install_breakpoint): Declare.
* ada-lang.c: Include exceptions.h.
<Ada exceptions description>: Update.
(struct ada_catchpoint_location): New type.
(ada_catchpoint_location_dtor): New function.
(ada_catchpoint_location_ops): New global.
(ada_catchpoint): New type.
(create_excep_cond_exprs): New function.
(dtor_exception, allocate_location_exception, re_set_exception)
(should_stop_exception, check_status_exception): New functions.
(print_one_exception, print_mention_exception)
(print_recreate_exception): Adjust.
(dtor_catch_exception, allocate_location_catch_exception)
(re_set_catch_exception, check_status_catch_exception): New
functions.
(catch_exception_breakpoint_ops): Install them.
(dtor_catch_exception_unhandled)
(allocate_location_catch_exception_unhandled)
(re_set_catch_exception_unhandled)
(check_status_catch_exception_unhandled): New functions.
(catch_exception_unhandled_breakpoint_ops): Install them.
(dtor_catch_assert, allocate_location_catch_assert)
(re_set_catch_assert, check_status_catch_assert): New functions.
(catch_assert_breakpoint_ops): Install them.
(ada_exception_catchpoint_p): Delete.
(catch_ada_exception_command_split)
(ada_exception_catchpoint_cond_string): Rename exp_string
parameter to excep_string. Adjust.
(ada_parse_catchpoint_condition): Delete.
(ada_exception_sal): Rename the exp_string parameter to
excep_string. Delete the cond_string and cond parameters.
Adjust.
(ada_decode_exception_location): Rename the exp_string parameter
to excep_string. Delete the cond_string and cond parameters.
Adjust.
(create_ada_exception_catchpoint): New function.
(catch_ada_exception_command, ada_decode_assert_location)
(catch_assert_command): Adjust.
* ada-lang.h (ada_exception_catchpoint_p): Delete declaration.
2011-06-22 Pedro Alves <pedro@codesourcery.com>
* ada-lang.c: Include arch-utils.h.

View File

@ -62,6 +62,7 @@
#include "value.h"
#include "mi/mi-common.h"
#include "arch-utils.h"
#include "exceptions.h"
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C).
@ -10395,19 +10396,7 @@ ada_modulus (struct type *type)
a few times already, and these changes affect the implementation
of these catchpoints. In order to be able to support several
variants of the runtime, we use a sniffer that will determine
the runtime variant used by the program being debugged.
At this time, we do not support the use of conditions on Ada exception
catchpoints. The COND and COND_STRING fields are therefore set
to NULL (most of the time, see below).
Conditions where EXP_STRING, COND, and COND_STRING are used:
When a user specifies the name of a specific exception in the case
of catchpoints on Ada exceptions, we store the name of that exception
in the EXP_STRING. We then translate this request into an actual
condition stored in COND_STRING, and then parse it into an expression
stored in COND. */
the runtime variant used by the program being debugged. */
/* The different types of catchpoints that we introduced for catching
Ada exceptions. */
@ -10744,6 +10733,215 @@ ada_exception_name_addr (enum exception_catchpoint_kind ex,
return result;
}
static struct symtab_and_line ada_exception_sal (enum exception_catchpoint_kind,
char *, char **,
struct breakpoint_ops **);
static char *ada_exception_catchpoint_cond_string (const char *excep_string);
/* Ada catchpoints.
In the case of catchpoints on Ada exceptions, the catchpoint will
stop the target on every exception the program throws. When a user
specifies the name of a specific exception, we translate this
request into a condition expression (in text form), and then parse
it into an expression stored in each of the catchpoint's locations.
We then use this condition to check whether the exception that was
raised is the one the user is interested in. If not, then the
target is resumed again. We store the name of the requested
exception, in order to be able to re-set the condition expression
when symbols change. */
/* An instance of this type is used to represent an Ada catchpoint
breakpoint location. It includes a "struct bp_location" as a kind
of base class; users downcast to "struct bp_location *" when
needed. */
struct ada_catchpoint_location
{
/* The base class. */
struct bp_location base;
/* The condition that checks whether the exception that was raised
is the specific exception the user specified on catchpoint
creation. */
struct expression *excep_cond_expr;
};
/* Implement the DTOR method in the bp_location_ops structure for all
Ada exception catchpoint kinds. */
static void
ada_catchpoint_location_dtor (struct bp_location *bl)
{
struct ada_catchpoint_location *al = (struct ada_catchpoint_location *) bl;
xfree (al->excep_cond_expr);
}
/* The vtable to be used in Ada catchpoint locations. */
static const struct bp_location_ops ada_catchpoint_location_ops =
{
ada_catchpoint_location_dtor
};
/* An instance of this type is used to represent an Ada catchpoint.
It includes a "struct breakpoint" as a kind of base class; users
downcast to "struct breakpoint *" when needed. */
struct ada_catchpoint
{
/* The base class. */
struct breakpoint base;
/* The name of the specific exception the user specified. */
char *excep_string;
};
/* Parse the exception condition string in the context of each of the
catchpoint's locations, and store them for later evaluation. */
static void
create_excep_cond_exprs (struct ada_catchpoint *c)
{
struct cleanup *old_chain;
struct bp_location *bl;
char *cond_string;
/* Nothing to do if there's no specific exception to catch. */
if (c->excep_string == NULL)
return;
/* Same if there are no locations... */
if (c->base.loc == NULL)
return;
/* Compute the condition expression in text form, from the specific
expection we want to catch. */
cond_string = ada_exception_catchpoint_cond_string (c->excep_string);
old_chain = make_cleanup (xfree, cond_string);
/* Iterate over all the catchpoint's locations, and parse an
expression for each. */
for (bl = c->base.loc; bl != NULL; bl = bl->next)
{
struct ada_catchpoint_location *ada_loc
= (struct ada_catchpoint_location *) bl;
struct expression *exp = NULL;
if (!bl->shlib_disabled)
{
volatile struct gdb_exception e;
char *s;
s = cond_string;
TRY_CATCH (e, RETURN_MASK_ERROR)
{
exp = parse_exp_1 (&s, block_for_pc (bl->address), 0);
}
if (e.reason < 0)
warning (_("failed to reevaluate internal exception condition "
"for catchpoint %d: %s"),
c->base.number, e.message);
}
ada_loc->excep_cond_expr = exp;
}
do_cleanups (old_chain);
}
/* Implement the DTOR method in the breakpoint_ops structure for all
exception catchpoint kinds. */
static void
dtor_exception (enum exception_catchpoint_kind ex, struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
xfree (c->excep_string);
}
/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
structure for all exception catchpoint kinds. */
static struct bp_location *
allocate_location_exception (enum exception_catchpoint_kind ex,
struct breakpoint *self)
{
struct ada_catchpoint_location *loc;
loc = XNEW (struct ada_catchpoint_location);
init_bp_location (&loc->base, &ada_catchpoint_location_ops, self);
loc->excep_cond_expr = NULL;
return &loc->base;
}
/* Implement the RE_SET method in the breakpoint_ops structure for all
exception catchpoint kinds. */
static void
re_set_exception (enum exception_catchpoint_kind ex, struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
/* Call the base class's method. This updates the catchpoint's
locations. */
breakpoint_re_set_default (b);
/* Reparse the exception conditional expressions. One for each
location. */
create_excep_cond_exprs (c);
}
/* Returns true if we should stop for this breakpoint hit. If the
user specified a specific exception, we only want to cause a stop
if the program thrown that exception. */
static int
should_stop_exception (const struct bp_location *bl)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) bl->owner;
const struct ada_catchpoint_location *ada_loc
= (const struct ada_catchpoint_location *) bl;
volatile struct gdb_exception ex;
int stop;
/* With no specific exception, should always stop. */
if (c->excep_string == NULL)
return 1;
if (ada_loc->excep_cond_expr == NULL)
{
/* We will have a NULL expression if back when we were creating
the expressions, this location's had failed to parse. */
return 1;
}
stop = 1;
TRY_CATCH (ex, RETURN_MASK_ALL)
{
struct value *mark;
mark = value_mark ();
stop = value_true (evaluate_expression (ada_loc->excep_cond_expr));
value_free_to_mark (mark);
}
if (ex.reason < 0)
exception_fprintf (gdb_stderr, ex,
_("Error in testing exception condition:\n"));
return stop;
}
/* Implement the CHECK_STATUS method in the breakpoint_ops structure
for all exception catchpoint kinds. */
static void
check_status_exception (enum exception_catchpoint_kind ex, bpstat bs)
{
bs->stop = should_stop_exception (bs->bp_location_at);
}
/* Implement the PRINT_IT method in the breakpoint_ops structure
for all exception catchpoint kinds. */
@ -10818,6 +11016,7 @@ static void
print_one_exception (enum exception_catchpoint_kind ex,
struct breakpoint *b, struct bp_location **last_loc)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
struct value_print_options opts;
get_user_print_options (&opts);
@ -10832,10 +11031,10 @@ print_one_exception (enum exception_catchpoint_kind ex,
switch (ex)
{
case ex_catch_exception:
if (b->exp_string != NULL)
if (c->excep_string != NULL)
{
char *msg = xstrprintf (_("`%s' Ada exception"), b->exp_string);
char *msg = xstrprintf (_("`%s' Ada exception"), c->excep_string);
ui_out_field_string (uiout, "what", msg);
xfree (msg);
}
@ -10865,12 +11064,14 @@ static void
print_mention_exception (enum exception_catchpoint_kind ex,
struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
switch (ex)
{
case ex_catch_exception:
if (b->exp_string != NULL)
if (c->excep_string != NULL)
printf_filtered (_("Catchpoint %d: `%s' Ada exception"),
b->number, b->exp_string);
b->number, c->excep_string);
else
printf_filtered (_("Catchpoint %d: all Ada exceptions"), b->number);
@ -10898,12 +11099,14 @@ static void
print_recreate_exception (enum exception_catchpoint_kind ex,
struct breakpoint *b, struct ui_file *fp)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
switch (ex)
{
case ex_catch_exception:
fprintf_filtered (fp, "catch exception");
if (b->exp_string != NULL)
fprintf_filtered (fp, " %s", b->exp_string);
if (c->excep_string != NULL)
fprintf_filtered (fp, " %s", c->excep_string);
break;
case ex_catch_exception_unhandled:
@ -10921,6 +11124,30 @@ print_recreate_exception (enum exception_catchpoint_kind ex,
/* Virtual table for "catch exception" breakpoints. */
static void
dtor_catch_exception (struct breakpoint *b)
{
dtor_exception (ex_catch_exception, b);
}
static struct bp_location *
allocate_location_catch_exception (struct breakpoint *self)
{
return allocate_location_exception (ex_catch_exception, self);
}
static void
re_set_catch_exception (struct breakpoint *b)
{
re_set_exception (ex_catch_exception, b);
}
static void
check_status_catch_exception (bpstat bs)
{
check_status_exception (ex_catch_exception, bs);
}
static enum print_stop_action
print_it_catch_exception (struct breakpoint *b)
{
@ -10947,10 +11174,13 @@ print_recreate_catch_exception (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops catch_exception_breakpoint_ops =
{
NULL, /* dtor */
dtor_catch_exception,
allocate_location_catch_exception,
re_set_catch_exception,
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
check_status_catch_exception,
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_exception,
@ -10962,6 +11192,30 @@ static struct breakpoint_ops catch_exception_breakpoint_ops =
/* Virtual table for "catch exception unhandled" breakpoints. */
static void
dtor_catch_exception_unhandled (struct breakpoint *b)
{
dtor_exception (ex_catch_exception_unhandled, b);
}
static struct bp_location *
allocate_location_catch_exception_unhandled (struct breakpoint *self)
{
return allocate_location_exception (ex_catch_exception_unhandled, self);
}
static void
re_set_catch_exception_unhandled (struct breakpoint *b)
{
re_set_exception (ex_catch_exception_unhandled, b);
}
static void
check_status_catch_exception_unhandled (bpstat bs)
{
check_status_exception (ex_catch_exception_unhandled, bs);
}
static enum print_stop_action
print_it_catch_exception_unhandled (struct breakpoint *b)
{
@ -10989,10 +11243,13 @@ print_recreate_catch_exception_unhandled (struct breakpoint *b,
}
static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
NULL, /* dtor */
dtor_catch_exception_unhandled,
allocate_location_catch_exception_unhandled,
re_set_catch_exception_unhandled,
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
check_status_catch_exception_unhandled,
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_exception_unhandled,
@ -11004,6 +11261,30 @@ static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops = {
/* Virtual table for "catch assert" breakpoints. */
static void
dtor_catch_assert (struct breakpoint *b)
{
dtor_exception (ex_catch_assert, b);
}
static struct bp_location *
allocate_location_catch_assert (struct breakpoint *self)
{
return allocate_location_exception (ex_catch_assert, self);
}
static void
re_set_catch_assert (struct breakpoint *b)
{
return re_set_exception (ex_catch_assert, b);
}
static void
check_status_catch_assert (bpstat bs)
{
check_status_exception (ex_catch_assert, bs);
}
static enum print_stop_action
print_it_catch_assert (struct breakpoint *b)
{
@ -11029,10 +11310,13 @@ print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
}
static struct breakpoint_ops catch_assert_breakpoint_ops = {
NULL, /* dtor */
dtor_catch_assert,
allocate_location_catch_assert,
re_set_catch_assert,
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
check_status_catch_assert,
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_assert,
@ -11042,16 +11326,6 @@ static struct breakpoint_ops catch_assert_breakpoint_ops = {
print_recreate_catch_assert
};
/* Return non-zero if B is an Ada exception catchpoint. */
int
ada_exception_catchpoint_p (struct breakpoint *b)
{
return (b->ops == &catch_exception_breakpoint_ops
|| b->ops == &catch_exception_unhandled_breakpoint_ops
|| b->ops == &catch_assert_breakpoint_ops);
}
/* Return a newly allocated copy of the first space-separated token
in ARGSP, and then adjust ARGSP to point immediately after that
token.
@ -11094,13 +11368,13 @@ ada_get_next_arg (char **argsp)
/* Split the arguments specified in a "catch exception" command.
Set EX to the appropriate catchpoint type.
Set EXP_STRING to the name of the specific exception if
Set EXCEP_STRING to the name of the specific exception if
specified by the user. */
static void
catch_ada_exception_command_split (char *args,
enum exception_catchpoint_kind *ex,
char **exp_string)
char **excep_string)
{
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
char *exception_name;
@ -11123,19 +11397,19 @@ catch_ada_exception_command_split (char *args,
{
/* Catch all exceptions. */
*ex = ex_catch_exception;
*exp_string = NULL;
*excep_string = NULL;
}
else if (strcmp (exception_name, "unhandled") == 0)
{
/* Catch unhandled exceptions. */
*ex = ex_catch_exception_unhandled;
*exp_string = NULL;
*excep_string = NULL;
}
else
{
/* Catch a specific exception. */
*ex = ex_catch_exception;
*exp_string = exception_name;
*excep_string = exception_name;
}
}
@ -11196,13 +11470,13 @@ ada_exception_breakpoint_ops (enum exception_catchpoint_kind ex)
deallocated later. */
static char *
ada_exception_catchpoint_cond_string (const char *exp_string)
ada_exception_catchpoint_cond_string (const char *excep_string)
{
int i;
/* The standard exceptions are a special case. They are defined in
runtime units that have been compiled without debugging info; if
EXP_STRING is the not-fully-qualified name of a standard
EXCEP_STRING is the not-fully-qualified name of a standard
exception (e.g. "constraint_error") then, during the evaluation
of the condition expression, the symbol lookup on this name would
*not* return this standard exception. The catchpoint condition
@ -11221,44 +11495,28 @@ ada_exception_catchpoint_cond_string (const char *exp_string)
for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
{
if (strcmp (standard_exc [i], exp_string) == 0)
if (strcmp (standard_exc [i], excep_string) == 0)
{
return xstrprintf ("long_integer (e) = long_integer (&standard.%s)",
exp_string);
excep_string);
}
}
return xstrprintf ("long_integer (e) = long_integer (&%s)", exp_string);
}
/* Return the expression corresponding to COND_STRING evaluated at SAL. */
static struct expression *
ada_parse_catchpoint_condition (char *cond_string,
struct symtab_and_line sal)
{
return (parse_exp_1 (&cond_string, block_for_pc (sal.pc), 0));
return xstrprintf ("long_integer (e) = long_integer (&%s)", excep_string);
}
/* Return the symtab_and_line that should be used to insert an exception
catchpoint of the TYPE kind.
EX_STRING should contain the name of a specific exception
that the catchpoint should catch, or NULL otherwise.
EXCEP_STRING should contain the name of a specific exception that
the catchpoint should catch, or NULL otherwise.
The idea behind all the remaining parameters is that their names match
the name of certain fields in the breakpoint structure that are used to
handle exception catchpoints. This function returns the value to which
these fields should be set, depending on the type of catchpoint we need
to create.
If COND and COND_STRING are both non-NULL, any value they might
hold will be free'ed, and then replaced by newly allocated ones.
These parameters are left untouched otherwise. */
ADDR_STRING returns the name of the function where the real
breakpoint that implements the catchpoints is set, depending on the
type of catchpoint we need to create. */
static struct symtab_and_line
ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
char **addr_string, char **cond_string,
struct expression **cond, struct breakpoint_ops **ops)
ada_exception_sal (enum exception_catchpoint_kind ex, char *excep_string,
char **addr_string, struct breakpoint_ops **ops)
{
const char *sym_name;
struct symbol *sym;
@ -11304,27 +11562,6 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
*addr_string = xstrdup (sym_name);
/* Set the COND and COND_STRING (if not NULL). */
if (cond_string != NULL && cond != NULL)
{
if (*cond_string != NULL)
{
xfree (*cond_string);
*cond_string = NULL;
}
if (*cond != NULL)
{
xfree (*cond);
*cond = NULL;
}
if (exp_string != NULL)
{
*cond_string = ada_exception_catchpoint_cond_string (exp_string);
*cond = ada_parse_catchpoint_condition (*cond_string, sal);
}
}
/* Set OPS. */
*ops = ada_exception_breakpoint_ops (ex);
@ -11333,7 +11570,6 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
/* Parse the arguments (ARGS) of the "catch exception" command.
Set TYPE to the appropriate exception catchpoint type.
If the user asked the catchpoint to catch only a specific
exception, then save the exception name in ADDR_STRING.
@ -11342,15 +11578,34 @@ ada_exception_sal (enum exception_catchpoint_kind ex, char *exp_string,
static struct symtab_and_line
ada_decode_exception_location (char *args, char **addr_string,
char **exp_string, char **cond_string,
struct expression **cond,
char **excep_string,
struct breakpoint_ops **ops)
{
enum exception_catchpoint_kind ex;
catch_ada_exception_command_split (args, &ex, exp_string);
return ada_exception_sal (ex, *exp_string, addr_string, cond_string,
cond, ops);
catch_ada_exception_command_split (args, &ex, excep_string);
return ada_exception_sal (ex, *excep_string, addr_string, ops);
}
/* Create an Ada exception catchpoint. */
static void
create_ada_exception_catchpoint (struct gdbarch *gdbarch,
struct symtab_and_line sal,
char *addr_string,
char *excep_string,
struct breakpoint_ops *ops,
int tempflag,
int from_tty)
{
struct ada_catchpoint *c;
c = XNEW (struct ada_catchpoint);
init_ada_exception_breakpoint (&c->base, gdbarch, sal, addr_string,
ops, tempflag, from_tty);
c->excep_string = excep_string;
create_excep_cond_exprs (c);
install_breakpoint (&c->base);
}
/* Implement the "catch exception" command. */
@ -11363,20 +11618,16 @@ catch_ada_exception_command (char *arg, int from_tty,
int tempflag;
struct symtab_and_line sal;
char *addr_string = NULL;
char *exp_string = NULL;
char *cond_string = NULL;
struct expression *cond = NULL;
char *excep_string = NULL;
struct breakpoint_ops *ops = NULL;
tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
if (!arg)
arg = "";
sal = ada_decode_exception_location (arg, &addr_string, &exp_string,
&cond_string, &cond, &ops);
create_ada_exception_breakpoint (gdbarch, sal, addr_string, exp_string,
cond_string, cond, ops, tempflag,
from_tty);
sal = ada_decode_exception_location (arg, &addr_string, &excep_string, &ops);
create_ada_exception_catchpoint (gdbarch, sal, addr_string,
excep_string, ops, tempflag, from_tty);
}
static struct symtab_and_line
@ -11393,8 +11644,7 @@ ada_decode_assert_location (char *args, char **addr_string,
error (_("Junk at end of arguments."));
}
return ada_exception_sal (ex_catch_assert, NULL, addr_string, NULL, NULL,
ops);
return ada_exception_sal (ex_catch_assert, NULL, addr_string, ops);
}
/* Implement the "catch assert" command. */
@ -11414,8 +11664,8 @@ catch_assert_command (char *arg, int from_tty,
if (!arg)
arg = "";
sal = ada_decode_assert_location (arg, &addr_string, &ops);
create_ada_exception_breakpoint (gdbarch, sal, addr_string, NULL, NULL, NULL,
ops, tempflag, from_tty);
create_ada_exception_catchpoint (gdbarch, sal, addr_string,
NULL, ops, tempflag, from_tty);
}
/* Operators */
/* Information about operators given special treatment in functions

View File

@ -385,6 +385,4 @@ extern void iterate_over_live_ada_tasks
extern int ada_build_task_list (int warn_if_null);
extern int ada_exception_catchpoint_p (struct breakpoint *b);
#endif

View File

@ -4313,6 +4313,13 @@ bpstat_stop_status (struct address_space *aspace,
b = bs->breakpoint_at;
if (b->ops != NULL && b->ops->check_status != NULL)
{
b->ops->check_status (bs);
if (!bs->stop)
continue;
}
if (b->type == bp_thread_event || b->type == bp_overlay_event
|| b->type == bp_longjmp_master
|| b->type == bp_std_terminate_master
@ -5009,11 +5016,8 @@ print_one_breakpoint_location (struct breakpoint *b,
ui_out_text (uiout, "\n");
}
if (!part_of_multiple && b->cond_string && !ada_exception_catchpoint_p (b))
if (!part_of_multiple && b->cond_string)
{
/* We do not print the condition for Ada exception catchpoints
because the condition is an internal implementation detail
that we do not want to expose to the user. */
annotate_field (7);
if (is_tracepoint (b))
ui_out_text (uiout, "\ttrace only if ");
@ -5685,22 +5689,19 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
}
}
/* Allocate a struct bp_location. */
static struct bp_location *
allocate_bp_location (struct breakpoint *bpt)
void
init_bp_location (struct bp_location *loc, const struct bp_location_ops *ops,
struct breakpoint *owner)
{
struct bp_location *loc;
loc = xmalloc (sizeof (struct bp_location));
memset (loc, 0, sizeof (*loc));
loc->owner = bpt;
loc->ops = ops;
loc->owner = owner;
loc->cond = NULL;
loc->shlib_disabled = 0;
loc->enabled = 1;
switch (bpt->type)
switch (owner->type)
{
case bp_breakpoint:
case bp_until:
@ -5745,12 +5746,29 @@ allocate_bp_location (struct breakpoint *bpt)
}
loc->refc = 1;
}
/* Allocate a struct bp_location. */
static struct bp_location *
allocate_bp_location (struct breakpoint *bpt)
{
struct bp_location *loc;
if (bpt->ops && bpt->ops->allocate_location)
return bpt->ops->allocate_location (bpt);
loc = xmalloc (sizeof (struct bp_location));
init_bp_location (loc, NULL, bpt);
return loc;
}
static void
free_bp_location (struct bp_location *loc)
{
if (loc->ops && loc->ops->dtor)
loc->ops->dtor (loc);
if (loc->cond)
xfree (loc->cond);
@ -5807,10 +5825,12 @@ add_to_breakpoint_chain (struct breakpoint *b)
static void
init_raw_breakpoint_without_location (struct breakpoint *b,
struct gdbarch *gdbarch,
enum bptype bptype)
enum bptype bptype,
struct breakpoint_ops *ops)
{
memset (b, 0, sizeof (*b));
b->ops = ops;
b->type = bptype;
b->gdbarch = gdbarch;
b->language = current_language->la_language;
@ -5822,7 +5842,6 @@ init_raw_breakpoint_without_location (struct breakpoint *b,
b->ignore_count = 0;
b->commands = NULL;
b->frame_id = null_frame_id;
b->ops = NULL;
b->condition_not_parsed = 0;
b->py_bp_object = NULL;
b->related_breakpoint = b;
@ -5839,7 +5858,7 @@ set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
{
struct breakpoint *b = XNEW (struct breakpoint);
init_raw_breakpoint_without_location (b, gdbarch, bptype);
init_raw_breakpoint_without_location (b, gdbarch, bptype, NULL);
add_to_breakpoint_chain (b);
return b;
}
@ -5911,12 +5930,13 @@ get_sal_arch (struct symtab_and_line sal)
static void
init_raw_breakpoint (struct breakpoint *b, struct gdbarch *gdbarch,
struct symtab_and_line sal, enum bptype bptype)
struct symtab_and_line sal, enum bptype bptype,
struct breakpoint_ops *ops)
{
CORE_ADDR adjusted_address;
struct gdbarch *loc_gdbarch;
init_raw_breakpoint_without_location (b, gdbarch, bptype);
init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
loc_gdbarch = get_sal_arch (sal);
if (!loc_gdbarch)
@ -5978,7 +5998,7 @@ set_raw_breakpoint (struct gdbarch *gdbarch,
{
struct breakpoint *b = XNEW (struct breakpoint);
init_raw_breakpoint (b, gdbarch, sal, bptype);
init_raw_breakpoint (b, gdbarch, sal, bptype, NULL);
add_to_breakpoint_chain (b);
return b;
}
@ -6381,9 +6401,12 @@ print_recreate_catch_fork (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops catch_fork_breakpoint_ops =
{
NULL, /* dtor */
NULL, /* allocate_location */
NULL, /* re_set */
insert_catch_fork,
remove_catch_fork,
breakpoint_hit_catch_fork,
NULL, /* check_status */
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_fork,
@ -6486,9 +6509,12 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops catch_vfork_breakpoint_ops =
{
NULL, /* dtor */
NULL, /* allocate_location */
NULL, /* re_set */
insert_catch_vfork,
remove_catch_vfork,
breakpoint_hit_catch_vfork,
NULL, /* check_status */
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_vfork,
@ -6812,9 +6838,12 @@ print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops catch_syscall_breakpoint_ops =
{
dtor_catch_syscall,
NULL, /* allocate_location */
NULL, /* re_set */
insert_catch_syscall,
remove_catch_syscall,
breakpoint_hit_catch_syscall,
NULL, /* check_status */
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_syscall,
@ -6845,26 +6874,17 @@ init_catchpoint (struct breakpoint *b,
{
struct symtab_and_line sal;
memset (b, 0, sizeof (*b));
init_sal (&sal);
sal.pspace = current_program_space;
init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint);
init_raw_breakpoint (b, gdbarch, sal, bp_catchpoint, ops);
b->cond_string = (cond_string == NULL) ? NULL : xstrdup (cond_string);
b->thread = -1;
b->addr_string = NULL;
b->enable_state = bp_enabled;
b->disposition = tempflag ? disp_del : disp_donttouch;
b->ops = ops;
}
/* Add breakpoint B on the breakpoint list, and notify the user, the
target and breakpoint_created observers of its existence. */
static void
install_catchpoint (struct breakpoint *b)
void
install_breakpoint (struct breakpoint *b)
{
add_to_breakpoint_chain (b);
set_breakpoint_count (breakpoint_count + 1);
@ -6885,7 +6905,7 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
c->forked_inferior_pid = null_ptid;
install_catchpoint (&c->base);
install_breakpoint (&c->base);
}
/* Exec catchpoints. */
@ -6991,9 +7011,12 @@ print_recreate_catch_exec (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops catch_exec_breakpoint_ops =
{
dtor_catch_exec,
NULL, /* allocate_location */
NULL, /* re_set */
insert_catch_exec,
remove_catch_exec,
breakpoint_hit_catch_exec,
NULL, /* check_status */
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_catch_exec,
@ -7014,7 +7037,7 @@ create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
c->syscalls_to_be_caught = filter;
install_catchpoint (&c->base);
install_breakpoint (&c->base);
}
static int
@ -8616,9 +8639,12 @@ print_recreate_ranged_breakpoint (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops ranged_breakpoint_ops =
{
NULL, /* dtor */
NULL, /* allocate_location */
NULL, /* re_set */
NULL, /* insert */
NULL, /* remove */
breakpoint_hit_ranged_breakpoint,
NULL, /* check_status */
resources_needed_ranged_breakpoint,
NULL, /* works_in_software_mode */
print_it_ranged_breakpoint,
@ -8942,9 +8968,12 @@ works_in_software_mode_watchpoint (const struct breakpoint *b)
static struct breakpoint_ops watchpoint_breakpoint_ops =
{
NULL, /* dtor */
NULL, /* allocate_location */
NULL, /* re_set */
insert_watchpoint,
remove_watchpoint,
NULL, /* breakpoint_hit */
NULL, /* check_status */
resources_needed_watchpoint,
works_in_software_mode_watchpoint,
NULL, /* print_it */
@ -9121,9 +9150,12 @@ print_recreate_masked_watchpoint (struct breakpoint *b, struct ui_file *fp)
static struct breakpoint_ops masked_watchpoint_breakpoint_ops =
{
NULL, /* dtor */
NULL, /* allocate_location */
NULL, /* re_set */
insert_masked_watchpoint,
remove_masked_watchpoint,
NULL, /* breakpoint_hit */
NULL, /* check_status */
resources_needed_masked_watchpoint,
works_in_software_mode_masked_watchpoint,
print_it_masked_watchpoint,
@ -9845,7 +9877,7 @@ catch_exec_command_1 (char *arg, int from_tty,
&catch_exec_breakpoint_ops);
c->exec_pathname = NULL;
install_catchpoint (&c->base);
install_breakpoint (&c->base);
}
static enum print_stop_action
@ -9937,9 +9969,12 @@ print_recreate_exception_catchpoint (struct breakpoint *b,
static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
NULL, /* dtor */
NULL, /* allocate_location */
NULL, /* re_set */
NULL, /* insert */
NULL, /* remove */
NULL, /* breakpoint_hit */
NULL, /* check_status */
NULL, /* resources_needed */
NULL, /* works_in_software_mode */
print_it_exception_catchpoint,
@ -10021,18 +10056,14 @@ catch_throw_command (char *arg, int from_tty, struct cmd_list_element *command)
}
void
create_ada_exception_breakpoint (struct gdbarch *gdbarch,
struct symtab_and_line sal,
char *addr_string,
char *exp_string,
char *cond_string,
struct expression *cond,
struct breakpoint_ops *ops,
int tempflag,
int from_tty)
init_ada_exception_breakpoint (struct breakpoint *b,
struct gdbarch *gdbarch,
struct symtab_and_line sal,
char *addr_string,
struct breakpoint_ops *ops,
int tempflag,
int from_tty)
{
struct breakpoint *b;
if (from_tty)
{
struct gdbarch *loc_gdbarch = get_sal_arch (sal);
@ -10051,24 +10082,12 @@ create_ada_exception_breakpoint (struct gdbarch *gdbarch,
enough for now, though. */
}
b = set_raw_breakpoint (gdbarch, sal, bp_breakpoint);
set_breakpoint_count (breakpoint_count + 1);
init_raw_breakpoint (b, gdbarch, sal, bp_breakpoint, ops);
b->enable_state = bp_enabled;
b->disposition = tempflag ? disp_del : disp_donttouch;
b->number = breakpoint_count;
b->ignore_count = 0;
b->loc->cond = cond;
b->addr_string = addr_string;
b->language = language_ada;
b->cond_string = cond_string;
b->exp_string = exp_string;
b->thread = -1;
b->ops = ops;
mention (b);
observer_notify_breakpoint_created (b);
update_global_location_list (1);
}
/* Cleanup function for a syscall filter list. */
@ -11402,23 +11421,13 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
return sals;
}
/* Reevaluate a hardware or software breakpoint and recreate its locations.
This is necessary after symbols are read (e.g., an executable or DSO
was loaded, or the inferior just started). */
static void
re_set_breakpoint (struct breakpoint *b)
void
breakpoint_re_set_default (struct breakpoint *b)
{
int found;
struct symtabs_and_lines sals, sals_end;
struct symtabs_and_lines expanded = {0};
struct symtabs_and_lines expanded_end = {0};
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
input_radix = b->input_radix;
save_current_space_and_thread ();
switch_to_program_space_and_thread (b->pspace);
set_language (b->language);
sals = addr_string_to_sals (b, b->addr_string, &found);
if (found)
@ -11438,7 +11447,21 @@ re_set_breakpoint (struct breakpoint *b)
}
update_breakpoint_locations (b, expanded, expanded_end);
do_cleanups (cleanups);
}
/* Prepare the global context for a re-set of breakpoint B. */
static struct cleanup *
prepare_re_set_context (struct breakpoint *b)
{
struct cleanup *cleanups;
input_radix = b->input_radix;
cleanups = save_current_space_and_thread ();
switch_to_program_space_and_thread (b->pspace);
set_language (b->language);
return cleanups;
}
/* Reset a breakpoint given it's struct breakpoint * BINT.
@ -11451,6 +11474,17 @@ breakpoint_re_set_one (void *bint)
/* Get past catch_errs. */
struct breakpoint *b = (struct breakpoint *) bint;
if (b->ops != NULL && b->ops->re_set != NULL)
{
struct cleanup *cleanups;
cleanups = prepare_re_set_context (b);
b->ops->re_set (b);
do_cleanups (cleanups);
return 0;
}
switch (b->type)
{
case bp_none:
@ -11474,7 +11508,13 @@ breakpoint_re_set_one (void *bint)
return 0;
}
re_set_breakpoint (b);
{
struct cleanup *cleanups;
cleanups = prepare_re_set_context (b);
breakpoint_re_set_default (b);
do_cleanups (cleanups);
}
break;
case bp_watchpoint:

View File

@ -30,6 +30,8 @@ struct block;
struct breakpoint_object;
struct get_number_or_range_state;
struct thread_info;
struct bpstats;
struct bp_location;
/* This is the maximum number of bytes a breakpoint instruction can
take. Feel free to increase it. It's just used in a few places to
@ -278,12 +280,26 @@ enum bp_loc_type
bp_loc_other /* Miscellaneous... */
};
/* This structure is a collection of function pointers that, if
available, will be called instead of performing the default action
for this bp_loc_type. */
struct bp_location_ops
{
/* Destructor. Releases everything from SELF (but not SELF
itself). */
void (*dtor) (struct bp_location *self);
};
struct bp_location
{
/* Chain pointer to the next breakpoint location for
the same parent breakpoint. */
struct bp_location *next;
/* Methods associated with this location. */
const struct bp_location_ops *ops;
/* The reference count. */
int refc;
@ -397,6 +413,14 @@ struct breakpoint_ops
itself). */
void (*dtor) (struct breakpoint *self);
/* Allocate a location for this breakpoint. */
struct bp_location * (*allocate_location) (struct breakpoint *);
/* Reevaluate a breakpoint. This is necessary after symbols change
(e.g., an executable or DSO was loaded, or the inferior just
started). */
void (*re_set) (struct breakpoint *self);
/* Insert the breakpoint or watchpoint or activate the catchpoint.
Return 0 for success, 1 if the breakpoint, watchpoint or catchpoint
type is not supported, -1 for failure. */
@ -408,11 +432,16 @@ struct breakpoint_ops
-1 for failure. */
int (*remove_location) (struct bp_location *);
/* Return non-zero if the debugger should tell the user that this
breakpoint was hit. */
int (*breakpoint_hit) (const struct bp_location *, struct address_space *,
/* Return true if it the target has stopped due to hitting
breakpoint location BL. This function does not check if we
should stop, only if BL explains the stop. */
int (*breakpoint_hit) (const struct bp_location *bl, struct address_space *,
CORE_ADDR);
/* Check internal conditions of the breakpoint referred to by BS.
If we should not stop for this breakpoint, set BS->stop to 0. */
void (*check_status) (struct bpstats *bs);
/* Tell how many hardware resources (debug registers) are needed
for this breakpoint. If this function is not provided, then
the breakpoint or watchpoint needs one debug register. */
@ -937,6 +966,12 @@ extern int breakpoint_thread_match (struct address_space *,
extern void until_break_command (char *, int, int);
/* Initialize a struct bp_location. */
extern void init_bp_location (struct bp_location *loc,
const struct bp_location_ops *ops,
struct breakpoint *owner);
extern void update_breakpoint_locations (struct breakpoint *b,
struct symtabs_and_lines sals,
struct symtabs_and_lines sals_end);
@ -945,6 +980,12 @@ extern void breakpoint_re_set (void);
extern void breakpoint_re_set_thread (struct breakpoint *);
/* The default re_set method, for typical hardware or software
breakpoints. Reevaluate the breakpoint and recreate its
locations. */
extern void breakpoint_re_set_default (struct breakpoint *);
extern struct breakpoint *set_momentary_breakpoint
(struct gdbarch *, struct symtab_and_line, struct frame_id, enum bptype);
@ -1001,18 +1042,21 @@ extern void
void *user_data_catch,
void *user_data_tcatch);
/* Create a breakpoint struct for Ada exception catchpoints. */
/* Initialize a breakpoint struct for Ada exception catchpoints. */
extern void
create_ada_exception_breakpoint (struct gdbarch *gdbarch,
struct symtab_and_line sal,
char *addr_string,
char *exp_string,
char *cond_string,
struct expression *cond,
struct breakpoint_ops *ops,
int tempflag,
int from_tty);
init_ada_exception_breakpoint (struct breakpoint *b,
struct gdbarch *gdbarch,
struct symtab_and_line sal,
char *addr_string,
struct breakpoint_ops *ops,
int tempflag,
int from_tty);
/* Add breakpoint B on the breakpoint list, and notify the user, the
target and breakpoint_created observers of its existence. */
extern void install_breakpoint (struct breakpoint *b);
extern int create_breakpoint (struct gdbarch *gdbarch, char *arg,
char *cond_string, int thread,