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:
parent
9ac4176b6d
commit
28010a5d42
@ -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.
|
||||
|
460
gdb/ada-lang.c
460
gdb/ada-lang.c
@ -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
|
||||
|
@ -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
|
||||
|
184
gdb/breakpoint.c
184
gdb/breakpoint.c
@ -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:
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user