X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fbreak-catch-throw.c;h=b1f9c32a8249bbf81954c463851fc68aa47f5166;hb=00c2093f698e8f40c04340cb1832d09e11ece237;hp=209c3e3b1123dadd8a5f9dfb7e70128a2843e3a0;hpb=00e52e5376c7ec604a739e6242e6be36221162d7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 209c3e3b11..b1f9c32a82 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -1,6 +1,6 @@ /* Everything about catch/throw catchpoints, for GDB. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -74,25 +74,21 @@ static struct breakpoint_ops gnu_v3_exception_catchpoint_ops; /* The type of an exception catchpoint. */ -struct exception_catchpoint +struct exception_catchpoint : public breakpoint { - /* The base class. */ - - struct breakpoint base; - /* The kind of exception catchpoint. */ enum exception_event_kind kind; - /* If non-NULL, an xmalloc'd string holding the source form of the - regular expression to match against. */ + /* If not empty, a string holding the source form of the regular + expression to match against. */ - char *exception_rx; + std::string exception_rx; - /* If non-NULL, an xmalloc'd, compiled regular expression which is - used to determine which exceptions to stop on. */ + /* If non-NULL, a compiled regular expression which is used to + determine which exceptions to stop on. */ - regex_t *pattern; + std::unique_ptr pattern; }; @@ -107,24 +103,23 @@ fetch_probe_arguments (struct value **arg0, struct value **arg1) struct frame_info *frame = get_selected_frame (_("No frame selected")); CORE_ADDR pc = get_frame_pc (frame); struct bound_probe pc_probe; - const struct sym_probe_fns *pc_probe_fns; unsigned n_args; pc_probe = find_probe_by_pc (pc); - if (pc_probe.probe == NULL - || strcmp (pc_probe.probe->provider, "libstdcxx") != 0 - || (strcmp (pc_probe.probe->name, "catch") != 0 - && strcmp (pc_probe.probe->name, "throw") != 0 - && strcmp (pc_probe.probe->name, "rethrow") != 0)) + if (pc_probe.prob == NULL + || pc_probe.prob->get_provider () != "libstdcxx" + || (pc_probe.prob->get_name () != "catch" + && pc_probe.prob->get_name () != "throw" + && pc_probe.prob->get_name () != "rethrow")) error (_("not stopped at a C++ exception catchpoint")); - n_args = get_probe_argument_count (pc_probe.probe, frame); + n_args = pc_probe.prob->get_argument_count (frame); if (n_args < 2) error (_("C++ exception catchpoint has too few arguments")); if (arg0 != NULL) - *arg0 = evaluate_probe_argument (pc_probe.probe, 0, frame); - *arg1 = evaluate_probe_argument (pc_probe.probe, 1, frame); + *arg0 = pc_probe.prob->evaluate_argument (0, frame); + *arg1 = pc_probe.prob->evaluate_argument (1, frame); if ((arg0 != NULL && *arg0 == NULL) || *arg1 == NULL) error (_("error computing probe argument at c++ exception catchpoint")); @@ -143,19 +138,6 @@ classify_exception_breakpoint (struct breakpoint *b) return cp->kind; } -/* Implement the 'dtor' method. */ - -static void -dtor_exception_catchpoint (struct breakpoint *self) -{ - struct exception_catchpoint *cp = (struct exception_catchpoint *) self; - - xfree (cp->exception_rx); - if (cp->pattern != NULL) - regfree (cp->pattern); - bkpt_breakpoint_ops.dtor (self); -} - /* Implement the 'check_status' method. */ static void @@ -163,7 +145,7 @@ check_status_exception_catchpoint (struct bpstats *bs) { struct exception_catchpoint *self = (struct exception_catchpoint *) bs->breakpoint_at; - char *type_name = NULL; + std::string type_name; bkpt_breakpoint_ops.check_status (bs); if (bs->stop == 0) @@ -175,17 +157,14 @@ check_status_exception_catchpoint (struct bpstats *bs) TRY { struct value *typeinfo_arg; - char *canon; + std::string canon; fetch_probe_arguments (NULL, &typeinfo_arg); type_name = cplus_typename_from_type_info (typeinfo_arg); - canon = cp_canonicalize_string (type_name); - if (canon != NULL) - { - xfree (type_name); - type_name = canon; - } + canon = cp_canonicalize_string (type_name.c_str ()); + if (!canon.empty ()) + std::swap (type_name, canon); } CATCH (e, RETURN_MASK_ERROR) { @@ -193,12 +172,10 @@ check_status_exception_catchpoint (struct bpstats *bs) } END_CATCH - if (type_name != NULL) + if (!type_name.empty ()) { - if (regexec (self->pattern, type_name, 0, NULL, 0) != 0) + if (self->pattern->exec (type_name.c_str (), 0, NULL, 0) != 0) bs->stop = 0; - - xfree (type_name); } } @@ -207,37 +184,31 @@ check_status_exception_catchpoint (struct bpstats *bs) static void re_set_exception_catchpoint (struct breakpoint *self) { - struct symtabs_and_lines sals = {0}; - struct symtabs_and_lines sals_end = {0}; - struct cleanup *cleanup; + std::vector sals; enum exception_event_kind kind = classify_exception_breakpoint (self); - struct event_location *location; + struct program_space *filter_pspace = current_program_space; /* We first try to use the probe interface. */ TRY { - location + event_location_up location = new_probe_location (exception_functions[kind].probe); - cleanup = make_cleanup_delete_event_location (location); - sals = parse_probes (location, NULL); - do_cleanups (cleanup); + sals = parse_probes (location.get (), filter_pspace, NULL); } - CATCH (e, RETURN_MASK_ERROR) { /* Using the probe interface failed. Let's fallback to the normal catchpoint mode. */ TRY { - struct explicit_location explicit; + struct explicit_location explicit_loc; - initialize_explicit_location (&explicit); - explicit.function_name + initialize_explicit_location (&explicit_loc); + explicit_loc.function_name = ASTRDUP (exception_functions[kind].function); - location = new_explicit_location (&explicit); - cleanup = make_cleanup_delete_event_location (location); - self->ops->decode_location (self, location, &sals); - do_cleanups (cleanup); + event_location_up location = new_explicit_location (&explicit_loc); + sals = self->ops->decode_location (self, location.get (), + filter_pspace); } CATCH (ex, RETURN_MASK_ERROR) { @@ -250,9 +221,7 @@ re_set_exception_catchpoint (struct breakpoint *self) } END_CATCH - cleanup = make_cleanup (xfree, sals.sals); - update_breakpoint_locations (self, sals, sals_end); - do_cleanups (cleanup); + update_breakpoint_locations (self, filter_pspace, sals, {}); } static enum print_stop_action @@ -264,23 +233,22 @@ print_it_exception_catchpoint (bpstat bs) enum exception_event_kind kind = classify_exception_breakpoint (b); annotate_catchpoint (b->number); + maybe_print_thread_hit_breakpoint (uiout); bp_temp = b->disposition == disp_del; - ui_out_text (uiout, - bp_temp ? "Temporary catchpoint " + uiout->text (bp_temp ? "Temporary catchpoint " : "Catchpoint "); - if (!ui_out_is_mi_like_p (uiout)) - ui_out_field_int (uiout, "bkptno", b->number); - ui_out_text (uiout, - (kind == EX_EVENT_THROW ? " (exception thrown), " + if (!uiout->is_mi_like_p ()) + uiout->field_int ("bkptno", b->number); + uiout->text ((kind == EX_EVENT_THROW ? " (exception thrown), " : (kind == EX_EVENT_CATCH ? " (exception caught), " : " (exception rethrown), "))); - if (ui_out_is_mi_like_p (uiout)) + if (uiout->is_mi_like_p ()) { - ui_out_field_string (uiout, "reason", + uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT)); - ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition)); - ui_out_field_int (uiout, "bkptno", b->number); + uiout->field_string ("disp", bpdisp_text (b->disposition)); + uiout->field_int ("bkptno", b->number); } return PRINT_SRC_AND_LOC; } @@ -298,9 +266,9 @@ print_one_exception_catchpoint (struct breakpoint *b, { annotate_field (4); if (b->loc == NULL || b->loc->shlib_disabled) - ui_out_field_string (uiout, "addr", ""); + uiout->field_string ("addr", ""); else - ui_out_field_core_addr (uiout, "addr", + uiout->field_core_addr ("addr", b->loc->gdbarch, b->loc->address); } annotate_field (5); @@ -310,21 +278,21 @@ print_one_exception_catchpoint (struct breakpoint *b, switch (kind) { case EX_EVENT_THROW: - ui_out_field_string (uiout, "what", "exception throw"); - if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "catch-type", "throw"); + uiout->field_string ("what", "exception throw"); + if (uiout->is_mi_like_p ()) + uiout->field_string ("catch-type", "throw"); break; case EX_EVENT_RETHROW: - ui_out_field_string (uiout, "what", "exception rethrow"); - if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "catch-type", "rethrow"); + uiout->field_string ("what", "exception rethrow"); + if (uiout->is_mi_like_p ()) + uiout->field_string ("catch-type", "rethrow"); break; case EX_EVENT_CATCH: - ui_out_field_string (uiout, "what", "exception catch"); - if (ui_out_is_mi_like_p (uiout)) - ui_out_field_string (uiout, "catch-type", "catch"); + uiout->field_string ("what", "exception catch"); + if (uiout->is_mi_like_p ()) + uiout->field_string ("catch-type", "catch"); break; } } @@ -338,11 +306,11 @@ print_one_detail_exception_catchpoint (const struct breakpoint *b, const struct exception_catchpoint *cp = (const struct exception_catchpoint *) b; - if (cp->exception_rx != NULL) + if (!cp->exception_rx.empty ()) { - ui_out_text (uiout, _("\tmatching: ")); - ui_out_field_string (uiout, "regexp", cp->exception_rx); - ui_out_text (uiout, "\n"); + uiout->text (_("\tmatching: ")); + uiout->field_string ("regexp", cp->exception_rx.c_str ()); + uiout->text ("\n"); } } @@ -354,10 +322,10 @@ print_mention_exception_catchpoint (struct breakpoint *b) enum exception_event_kind kind = classify_exception_breakpoint (b); bp_temp = b->disposition == disp_del; - ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ") + uiout->text (bp_temp ? _("Temporary catchpoint ") : _("Catchpoint ")); - ui_out_field_int (uiout, "bkptno", b->number); - ui_out_text (uiout, (kind == EX_EVENT_THROW ? _(" (throw)") + uiout->field_int ("bkptno", b->number); + uiout->text ((kind == EX_EVENT_THROW ? _(" (throw)") : (kind == EX_EVENT_CATCH ? _(" (catch)") : _(" (rethrow)")))); } @@ -390,38 +358,32 @@ print_recreate_exception_catchpoint (struct breakpoint *b, } static void -handle_gnu_v3_exceptions (int tempflag, char *except_rx, char *cond_string, +handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx, + const char *cond_string, enum exception_event_kind ex_event, int from_tty) { - struct exception_catchpoint *cp; - struct cleanup *cleanup = make_cleanup (null_cleanup, NULL); - regex_t *pattern = NULL; + std::unique_ptr pattern; - if (except_rx != NULL) + if (!except_rx.empty ()) { - pattern = XNEW (regex_t); - make_cleanup (xfree, pattern); - - compile_rx_or_error (pattern, except_rx, - _("invalid type-matching regexp")); + pattern.reset (new compiled_regex (except_rx.c_str (), REG_NOSUB, + _("invalid type-matching regexp"))); } - cp = XCNEW (struct exception_catchpoint); - make_cleanup (xfree, cp); + std::unique_ptr cp (new exception_catchpoint ()); - init_catchpoint (&cp->base, get_current_arch (), tempflag, cond_string, + init_catchpoint (cp.get (), get_current_arch (), tempflag, cond_string, &gnu_v3_exception_catchpoint_ops); /* We need to reset 'type' in order for code in breakpoint.c to do the right thing. */ - cp->base.type = bp_breakpoint; + cp->type = bp_breakpoint; cp->kind = ex_event; - cp->exception_rx = except_rx; - cp->pattern = pattern; + cp->exception_rx = std::move (except_rx); + cp->pattern = std::move (pattern); - re_set_exception_catchpoint (&cp->base); + re_set_exception_catchpoint (cp.get ()); - install_breakpoint (0, &cp->base, 1); - discard_cleanups (cleanup); + install_breakpoint (0, std::move (cp), 1); } /* Look for an "if" token in *STRING. The "if" token must be preceded @@ -434,11 +396,11 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx, char *cond_string, STRING is updated to point to the "if" token, if it exists, or to the end of the string. */ -static char * -extract_exception_regexp (char **string) +static std::string +extract_exception_regexp (const char **string) { - char *start; - char *last, *last_space; + const char *start; + const char *last, *last_space; start = skip_spaces (*string); @@ -446,7 +408,7 @@ extract_exception_regexp (char **string) last_space = start; while (*last != '\0') { - char *if_token = last; + const char *if_token = last; /* Check for the "if". */ if (check_for_argument (&if_token, "if", 2)) @@ -459,27 +421,25 @@ extract_exception_regexp (char **string) *string = last; if (last_space > start) - return savestring (start, last_space - start); - return NULL; + return std::string (start, last_space - start); + return std::string (); } /* Deal with "catch catch", "catch throw", and "catch rethrow" commands. */ static void -catch_exception_command_1 (enum exception_event_kind ex_event, char *arg, +catch_exception_command_1 (enum exception_event_kind ex_event, + const char *arg, int tempflag, int from_tty) { - char *except_rx; - char *cond_string = NULL; - struct cleanup *cleanup; + const char *cond_string = NULL; if (!arg) arg = ""; arg = skip_spaces (arg); - except_rx = extract_exception_regexp (&arg); - cleanup = make_cleanup (xfree, except_rx); + std::string except_rx = extract_exception_regexp (&arg); cond_string = ep_parse_optional_if_clause (&arg); @@ -491,16 +451,15 @@ catch_exception_command_1 (enum exception_event_kind ex_event, char *arg, && ex_event != EX_EVENT_RETHROW) error (_("Unsupported or unknown exception event; cannot catch it")); - handle_gnu_v3_exceptions (tempflag, except_rx, cond_string, + handle_gnu_v3_exceptions (tempflag, std::move (except_rx), cond_string, ex_event, from_tty); - - discard_cleanups (cleanup); } /* Implementation of "catch catch" command. */ static void -catch_catch_command (char *arg, int from_tty, struct cmd_list_element *command) +catch_catch_command (const char *arg, int from_tty, + struct cmd_list_element *command) { int tempflag = get_cmd_context (command) == CATCH_TEMPORARY; @@ -510,7 +469,8 @@ catch_catch_command (char *arg, int from_tty, struct cmd_list_element *command) /* Implementation of "catch throw" command. */ static void -catch_throw_command (char *arg, int from_tty, struct cmd_list_element *command) +catch_throw_command (const char *arg, int from_tty, + struct cmd_list_element *command) { int tempflag = get_cmd_context (command) == CATCH_TEMPORARY; @@ -520,7 +480,7 @@ catch_throw_command (char *arg, int from_tty, struct cmd_list_element *command) /* Implementation of "catch rethrow" command. */ static void -catch_rethrow_command (char *arg, int from_tty, +catch_rethrow_command (const char *arg, int from_tty, struct cmd_list_element *command) { int tempflag = get_cmd_context (command) == CATCH_TEMPORARY; @@ -569,7 +529,6 @@ initialize_throw_catchpoint_ops (void) /* GNU v3 exception catchpoints. */ ops = &gnu_v3_exception_catchpoint_ops; *ops = bkpt_breakpoint_ops; - ops->dtor = dtor_exception_catchpoint; ops->re_set = re_set_exception_catchpoint; ops->print_it = print_it_exception_catchpoint; ops->print_one = print_one_exception_catchpoint; @@ -579,8 +538,6 @@ initialize_throw_catchpoint_ops (void) ops->check_status = check_status_exception_catchpoint; } -initialize_file_ftype _initialize_break_catch_throw; - void _initialize_break_catch_throw (void) {