#include "valprint.h"
#include "source.h"
#include "observable.h"
-#include "gdbsupport/vec.h"
#include "stack.h"
#include "gdbsupport/gdb_vecs.h"
#include "typeprint.h"
case LOC_CONST:
return SYMBOL_VALUE (sym0) == SYMBOL_VALUE (sym1)
&& equiv_types (SYMBOL_TYPE (sym0), SYMBOL_TYPE (sym1));
+
+ case LOC_STATIC:
+ {
+ const char *name0 = SYMBOL_LINKAGE_NAME (sym0);
+ const char *name1 = SYMBOL_LINKAGE_NAME (sym1);
+ return (strcmp (name0, name1) == 0
+ && SYMBOL_VALUE_ADDRESS (sym0) == SYMBOL_VALUE_ADDRESS (sym1));
+ }
+
default:
return 0;
}
return result;
}
-/* Return all the bound minimal symbols matching NAME according to Ada
- decoding rules. Returns an empty vector if there is no such
- minimal symbol. Names prefixed with "standard__" are handled
- specially: "standard__" is first stripped off, and only static and
- global symbols are searched. */
-
-static std::vector<struct bound_minimal_symbol>
-ada_lookup_simple_minsyms (const char *name)
-{
- std::vector<struct bound_minimal_symbol> result;
-
- symbol_name_match_type match_type = name_match_type_from_name (name);
- lookup_name_info lookup_name (name, match_type);
-
- symbol_name_matcher_ftype *match_name
- = ada_get_symbol_name_matcher (lookup_name);
-
- for (objfile *objfile : current_program_space->objfiles ())
- {
- for (minimal_symbol *msymbol : objfile->msymbols ())
- {
- if (match_name (MSYMBOL_LINKAGE_NAME (msymbol), lookup_name, NULL)
- && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
- result.push_back ({msymbol, objfile});
- }
- }
-
- return result;
-}
-
/* For all subprograms that statically enclose the subprogram of the
selected frame, add symbols matching identifier NAME in DOMAIN
and their blocks to the list of data in OBSTACKP, as for
struct ada_catchpoint : public breakpoint
{
+ explicit ada_catchpoint (enum ada_exception_catchpoint_kind kind)
+ : m_kind (kind)
+ {
+ }
+
/* The name of the specific exception the user specified. */
std::string excep_string;
+
+ /* What kind of catchpoint this is. */
+ enum ada_exception_catchpoint_kind m_kind;
};
/* Parse the exception condition string in the context of each of the
create_excep_cond_exprs (struct ada_catchpoint *c,
enum ada_exception_catchpoint_kind ex)
{
+ struct bp_location *bl;
+
/* Nothing to do if there's no specific exception to catch. */
if (c->excep_string.empty ())
return;
if (c->loc == NULL)
return;
- /* We have to compute the expression once for each program space,
- because the expression may hold the addresses of multiple symbols
- in some cases. */
- std::multimap<program_space *, struct bp_location *> loc_map;
- for (bp_location *bl = c->loc; bl != NULL; bl = bl->next)
- loc_map.emplace (bl->pspace, bl);
-
- scoped_restore_current_program_space save_pspace;
+ /* Compute the condition expression in text form, from the specific
+ expection we want to catch. */
+ std::string cond_string
+ = ada_exception_catchpoint_cond_string (c->excep_string.c_str (), ex);
- std::string cond_string;
- program_space *last_ps = nullptr;
- for (auto iter : loc_map)
+ /* Iterate over all the catchpoint's locations, and parse an
+ expression for each. */
+ for (bl = c->loc; bl != NULL; bl = bl->next)
{
struct ada_catchpoint_location *ada_loc
- = (struct ada_catchpoint_location *) iter.second;
-
- if (ada_loc->pspace != last_ps)
- {
- last_ps = ada_loc->pspace;
- set_current_program_space (last_ps);
-
- /* 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.c_str (),
- ex);
- }
-
+ = (struct ada_catchpoint_location *) bl;
expression_up exp;
- if (!ada_loc->shlib_disabled)
+ if (!bl->shlib_disabled)
{
const char *s;
s = cond_string.c_str ();
try
{
- exp = parse_exp_1 (&s, ada_loc->address,
- block_for_pc (ada_loc->address),
+ exp = parse_exp_1 (&s, bl->address,
+ block_for_pc (bl->address),
0);
}
catch (const gdb_exception_error &e)
structure for all exception catchpoint kinds. */
static struct bp_location *
-allocate_location_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *self)
+allocate_location_exception (struct breakpoint *self)
{
return new ada_catchpoint_location (self);
}
exception catchpoint kinds. */
static void
-re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
+re_set_exception (struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
/* Reparse the exception conditional expressions. One for each
location. */
- create_excep_cond_exprs (c, ex);
+ create_excep_cond_exprs (c, c->m_kind);
}
/* Returns true if we should stop for this breakpoint hit. If the
= (const struct ada_catchpoint_location *) bl;
int stop;
+ struct internalvar *var = lookup_internalvar ("_ada_exception");
+ if (c->m_kind == ada_catch_assert)
+ clear_internalvar (var);
+ else
+ {
+ try
+ {
+ const char *expr;
+
+ if (c->m_kind == ada_catch_handlers)
+ expr = ("GNAT_GCC_exception_Access(gcc_exception)"
+ ".all.occurrence.id");
+ else
+ expr = "e";
+
+ struct value *exc = parse_and_eval (expr);
+ set_internalvar (var, exc);
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ clear_internalvar (var);
+ }
+ }
+
/* With no specific exception, should always stop. */
if (c->excep_string.empty ())
return 1;
for all exception catchpoint kinds. */
static void
-check_status_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
+check_status_exception (bpstat bs)
{
bs->stop = should_stop_exception (bs->bp_location_at);
}
for all exception catchpoint kinds. */
static enum print_stop_action
-print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
+print_it_exception (bpstat bs)
{
struct ui_out *uiout = current_uiout;
struct breakpoint *b = bs->breakpoint_at;
ada_find_printable_frame). */
select_frame (get_current_frame ());
- switch (ex)
+ struct ada_catchpoint *c = (struct ada_catchpoint *) b;
+ switch (c->m_kind)
{
case ada_catch_exception:
case ada_catch_exception_unhandled:
case ada_catch_handlers:
{
- const CORE_ADDR addr = ada_exception_name_addr (ex, b);
+ const CORE_ADDR addr = ada_exception_name_addr (c->m_kind, b);
char exception_name[256];
if (addr != 0)
it clearer to the user which kind of catchpoint just got
hit. We used ui_out_text to make sure that this extra
info does not pollute the exception name in the MI case. */
- if (ex == ada_catch_exception_unhandled)
+ if (c->m_kind == ada_catch_exception_unhandled)
uiout->text ("unhandled ");
uiout->field_string ("exception-name", exception_name);
}
for all exception catchpoint kinds. */
static void
-print_one_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *b, struct bp_location **last_loc)
+print_one_exception (struct breakpoint *b, struct bp_location **last_loc)
{
struct ui_out *uiout = current_uiout;
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
uiout->field_skip ("addr");
annotate_field (5);
- switch (ex)
+ switch (c->m_kind)
{
case ada_catch_exception:
if (!c->excep_string.empty ())
for all exception catchpoint kinds. */
static void
-print_mention_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *b)
+print_mention_exception (struct breakpoint *b)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
struct ui_out *uiout = current_uiout;
uiout->field_signed ("bkptno", b->number);
uiout->text (": ");
- switch (ex)
+ switch (c->m_kind)
{
case ada_catch_exception:
if (!c->excep_string.empty ())
for all exception catchpoint kinds. */
static void
-print_recreate_exception (enum ada_exception_catchpoint_kind ex,
- struct breakpoint *b, struct ui_file *fp)
+print_recreate_exception (struct breakpoint *b, struct ui_file *fp)
{
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
- switch (ex)
+ switch (c->m_kind)
{
case ada_catch_exception:
fprintf_filtered (fp, "catch exception");
print_recreate_thread (b, fp);
}
-/* Virtual table for "catch exception" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_exception (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_exception, self);
-}
-
-static void
-re_set_catch_exception (struct breakpoint *b)
-{
- re_set_exception (ada_catch_exception, b);
-}
-
-static void
-check_status_catch_exception (bpstat bs)
-{
- check_status_exception (ada_catch_exception, bs);
-}
-
-static enum print_stop_action
-print_it_catch_exception (bpstat bs)
-{
- return print_it_exception (ada_catch_exception, bs);
-}
-
-static void
-print_one_catch_exception (struct breakpoint *b, struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_exception, b, last_loc);
-}
-
-static void
-print_mention_catch_exception (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_exception, b);
-}
-
-static void
-print_recreate_catch_exception (struct breakpoint *b, struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_exception, b, fp);
-}
-
+/* Virtual tables for various breakpoint types. */
static struct breakpoint_ops catch_exception_breakpoint_ops;
-
-/* Virtual table for "catch exception unhandled" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_exception_unhandled (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_exception_unhandled, self);
-}
-
-static void
-re_set_catch_exception_unhandled (struct breakpoint *b)
-{
- re_set_exception (ada_catch_exception_unhandled, b);
-}
-
-static void
-check_status_catch_exception_unhandled (bpstat bs)
-{
- check_status_exception (ada_catch_exception_unhandled, bs);
-}
-
-static enum print_stop_action
-print_it_catch_exception_unhandled (bpstat bs)
-{
- return print_it_exception (ada_catch_exception_unhandled, bs);
-}
-
-static void
-print_one_catch_exception_unhandled (struct breakpoint *b,
- struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_exception_unhandled, b, last_loc);
-}
-
-static void
-print_mention_catch_exception_unhandled (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_exception_unhandled, b);
-}
-
-static void
-print_recreate_catch_exception_unhandled (struct breakpoint *b,
- struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_exception_unhandled, b, fp);
-}
-
static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops;
-
-/* Virtual table for "catch assert" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_assert (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_assert, self);
-}
-
-static void
-re_set_catch_assert (struct breakpoint *b)
-{
- re_set_exception (ada_catch_assert, b);
-}
-
-static void
-check_status_catch_assert (bpstat bs)
-{
- check_status_exception (ada_catch_assert, bs);
-}
-
-static enum print_stop_action
-print_it_catch_assert (bpstat bs)
-{
- return print_it_exception (ada_catch_assert, bs);
-}
-
-static void
-print_one_catch_assert (struct breakpoint *b, struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_assert, b, last_loc);
-}
-
-static void
-print_mention_catch_assert (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_assert, b);
-}
-
-static void
-print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_assert, b, fp);
-}
-
static struct breakpoint_ops catch_assert_breakpoint_ops;
-
-/* Virtual table for "catch handlers" breakpoints. */
-
-static struct bp_location *
-allocate_location_catch_handlers (struct breakpoint *self)
-{
- return allocate_location_exception (ada_catch_handlers, self);
-}
-
-static void
-re_set_catch_handlers (struct breakpoint *b)
-{
- re_set_exception (ada_catch_handlers, b);
-}
-
-static void
-check_status_catch_handlers (bpstat bs)
-{
- check_status_exception (ada_catch_handlers, bs);
-}
-
-static enum print_stop_action
-print_it_catch_handlers (bpstat bs)
-{
- return print_it_exception (ada_catch_handlers, bs);
-}
-
-static void
-print_one_catch_handlers (struct breakpoint *b,
- struct bp_location **last_loc)
-{
- print_one_exception (ada_catch_handlers, b, last_loc);
-}
-
-static void
-print_mention_catch_handlers (struct breakpoint *b)
-{
- print_mention_exception (ada_catch_handlers, b);
-}
-
-static void
-print_recreate_catch_handlers (struct breakpoint *b,
- struct ui_file *fp)
-{
- print_recreate_exception (ada_catch_handlers, b, fp);
-}
-
static struct breakpoint_ops catch_handlers_breakpoint_ops;
/* See ada-lang.h. */
enum ada_exception_catchpoint_kind ex)
{
int i;
+ bool is_standard_exc = false;
std::string result;
- const char *name;
if (ex == ada_catch_handlers)
{
/* For exception handlers catchpoints, the condition string does
not use the same parameter as for the other exceptions. */
- name = ("long_integer (GNAT_GCC_exception_Access"
- "(gcc_exception).all.occurrence.id)");
+ result = ("long_integer (GNAT_GCC_exception_Access"
+ "(gcc_exception).all.occurrence.id)");
}
else
- name = "long_integer (e)";
+ result = "long_integer (e)";
/* The standard exceptions are a special case. They are defined in
runtime units that have been compiled without debugging info; if
If an exception named contraint_error is defined in another package of
the inferior program, then the only way to specify this exception as a
breakpoint condition is to use its fully-qualified named:
- e.g. my_package.constraint_error.
+ e.g. my_package.constraint_error. */
- Furthermore, in some situations a standard exception's symbol may
- be present in more than one objfile, because the compiler may
- choose to emit copy relocations for them. So, we have to compare
- against all the possible addresses. */
-
- /* Storage for a rewritten symbol name. */
- std::string std_name;
for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
{
if (strcmp (standard_exc [i], excep_string) == 0)
{
- std_name = std::string ("standard.") + excep_string;
- excep_string = std_name.c_str ();
+ is_standard_exc = true;
break;
}
}
- excep_string = ada_encode (excep_string);
- std::vector<struct bound_minimal_symbol> symbols
- = ada_lookup_simple_minsyms (excep_string);
- for (const bound_minimal_symbol &msym : symbols)
- {
- if (!result.empty ())
- result += " or ";
- string_appendf (result, "%s = %s", name,
- pulongest (BMSYMBOL_VALUE_ADDRESS (msym)));
- }
+ result += " = ";
+
+ if (is_standard_exc)
+ string_appendf (result, "long_integer (&standard.%s)", excep_string);
+ else
+ string_appendf (result, "long_integer (&%s)", excep_string);
return result;
}
const struct breakpoint_ops *ops = NULL;
struct symtab_and_line sal = ada_exception_sal (ex_kind, &addr_string, &ops);
- std::unique_ptr<ada_catchpoint> c (new ada_catchpoint ());
+ std::unique_ptr<ada_catchpoint> c (new ada_catchpoint (ex_kind));
init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string.c_str (),
ops, tempflag, disabled, from_tty);
c->excep_string = excep_string;
ops = &catch_exception_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_exception;
- ops->re_set = re_set_catch_exception;
- ops->check_status = check_status_catch_exception;
- ops->print_it = print_it_catch_exception;
- ops->print_one = print_one_catch_exception;
- ops->print_mention = print_mention_catch_exception;
- ops->print_recreate = print_recreate_catch_exception;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
ops = &catch_exception_unhandled_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_exception_unhandled;
- ops->re_set = re_set_catch_exception_unhandled;
- ops->check_status = check_status_catch_exception_unhandled;
- ops->print_it = print_it_catch_exception_unhandled;
- ops->print_one = print_one_catch_exception_unhandled;
- ops->print_mention = print_mention_catch_exception_unhandled;
- ops->print_recreate = print_recreate_catch_exception_unhandled;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
ops = &catch_assert_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_assert;
- ops->re_set = re_set_catch_assert;
- ops->check_status = check_status_catch_assert;
- ops->print_it = print_it_catch_assert;
- ops->print_one = print_one_catch_assert;
- ops->print_mention = print_mention_catch_assert;
- ops->print_recreate = print_recreate_catch_assert;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
ops = &catch_handlers_breakpoint_ops;
*ops = bkpt_breakpoint_ops;
- ops->allocate_location = allocate_location_catch_handlers;
- ops->re_set = re_set_catch_handlers;
- ops->check_status = check_status_catch_handlers;
- ops->print_it = print_it_catch_handlers;
- ops->print_one = print_one_catch_handlers;
- ops->print_mention = print_mention_catch_handlers;
- ops->print_recreate = print_recreate_catch_handlers;
+ ops->allocate_location = allocate_location_exception;
+ ops->re_set = re_set_exception;
+ ops->check_status = check_status_exception;
+ ops->print_it = print_it_exception;
+ ops->print_one = print_one_exception;
+ ops->print_mention = print_mention_exception;
+ ops->print_recreate = print_recreate_exception;
}
/* This module's 'new_objfile' observer. */