/* Everything about breakpoints, for GDB.
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "ax-gdb.h"
#include "dummy-frame.h"
#include "interps.h"
-#include "format.h"
+#include "common/format.h"
#include "thread-fsm.h"
#include "tid-parse.h"
+#include "cli/cli-style.h"
+#include "mi/mi-main.h"
/* readline include files */
#include "readline/readline.h"
}
else if (target_has_execution)
{
- struct thread_info *tp;
-
if (always_inserted_mode)
{
/* The user wants breakpoints inserted even if all threads
/* Don't remove breakpoints yet if, even though all threads are
stopped, we still have events to process. */
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : all_non_exited_threads ())
if (tp->resumed
&& tp->suspend.waitstatus_pending_p)
return 1;
/* The locations that no longer correspond to any breakpoint, unlinked
from the bp_locations array, but for which a hit may still be
reported by a target. */
-VEC(bp_location_p) *moribund_locations = NULL;
+static std::vector<bp_location *> moribund_locations;
/* Number of last breakpoint made. */
{
struct watchpoint *w = (struct watchpoint *) b;
- innermost_block.reset ();
+ innermost_block_tracker tracker;
arg = exp;
- w->cond_exp = parse_exp_1 (&arg, 0, 0, 0);
+ w->cond_exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
if (*arg)
error (_("Junk at end of expression"));
- w->cond_exp_valid_block = innermost_block.block ();
+ w->cond_exp_valid_block = tracker.block ();
}
else
{
for (c = commands; c; c = c->next)
{
- int i;
-
if (c->control_type == while_stepping_control)
error (_("The 'while-stepping' command can "
"only be used for tracepoints"));
/* Return a vector of all the static tracepoints set at ADDR. The
caller is responsible for releasing the vector. */
-VEC(breakpoint_p) *
+std::vector<breakpoint *>
static_tracepoints_here (CORE_ADDR addr)
{
struct breakpoint *b;
- VEC(breakpoint_p) *found = 0;
+ std::vector<breakpoint *> found;
struct bp_location *loc;
ALL_BREAKPOINTS (b)
{
for (loc = b->loc; loc; loc = loc->next)
if (loc->address == addr)
- VEC_safe_push(breakpoint_p, found, b);
+ found.push_back (b);
}
return found;
gdb::observers::breakpoint_modified.notify (b);
}
-void
-check_tracepoint_command (char *line, void *closure)
-{
- struct breakpoint *b = (struct breakpoint *) closure;
-
- validate_actionline (line, b);
-}
-
static void
commands_command_1 (const char *arg, int from_tty,
struct command_line *control)
{
counted_command_line cmd;
+ /* cmd_read will be true once we have read cmd. Note that cmd might still be
+ NULL after the call to read_command_lines if the user provides an empty
+ list of command by just typing "end". */
+ bool cmd_read = false;
std::string new_arg;
map_breakpoint_numbers
(arg, [&] (breakpoint *b)
{
- if (cmd == NULL)
+ if (!cmd_read)
{
+ gdb_assert (cmd == NULL);
if (control != NULL)
cmd = control->body_list_0;
else
"%s, one per line."),
arg);
- cmd = read_command_lines (&str[0],
- from_tty, 1,
- (is_tracepoint (b)
- ? check_tracepoint_command : 0),
- b);
+ auto do_validate = [=] (const char *line)
+ {
+ validate_actionline (line, b);
+ };
+ gdb::function_view<void (const char *)> validator;
+ if (is_tracepoint (b))
+ validator = do_validate;
+
+ cmd = read_command_lines (str.c_str (), from_tty, 1, validator);
}
+ cmd_read = true;
}
/* If a breakpoint was on the list more than once, we don't need to
watchpoint_in_thread_scope (struct watchpoint *b)
{
return (b->pspace == current_program_space
- && (ptid_equal (b->watchpoint_thread, null_ptid)
- || (ptid_equal (inferior_ptid, b->watchpoint_thread)
- && !is_executing (inferior_ptid))));
+ && (b->watchpoint_thread == null_ptid
+ || (inferior_ptid == b->watchpoint_thread
+ && !inferior_thread ()->executing)));
}
/* Set watchpoint B to disp_del_at_next_stop, even including its possible
{
int pc = 0;
std::vector<value_ref_ptr> val_chain;
- struct value *v, *result, *next;
+ struct value *v, *result;
struct program_space *frame_pspace;
fetch_subexp_value (b->exp.get (), &pc, &v, &result, &val_chain, 0);
/* We don't want to stop processing, so catch any errors
that may show up. */
- TRY
+ try
{
aexpr = gen_eval_for_expr (scope, cond);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
/* If we got here, it means the condition could not be parsed to a valid
bytecode expression and thus can't be evaluated on the target's side.
It's no use iterating through the conditions. */
}
- END_CATCH
/* We have a valid agent expression. */
return aexpr;
/* We don't want to stop processing, so catch any errors
that may show up. */
- TRY
+ try
{
aexpr = gen_printf (scope, gdbarch, 0, 0,
format_start, format_end - format_start,
argvec.size (), argvec.data ());
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
/* If we got here, it means the command could not be parsed to a valid
bytecode expression and thus can't be evaluated on the target's side.
It's no use iterating through the other commands. */
}
- END_CATCH
/* We have a valid agent expression, return it. */
return aexpr;
struct thread_info *thr = find_thread_global_id (bl->owner->thread);
struct regcache *regcache;
- regcache = get_thread_regcache (thr->ptid);
+ regcache = get_thread_regcache (thr);
return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
regcache, addr);
|| !(section_is_overlay (bl->section)))
{
/* No overlay handling: just set the breakpoint. */
- TRY
+ try
{
int val;
if (val)
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
- CATCH (e, RETURN_MASK_ALL)
+ catch (const gdb_exception &e)
{
bp_excpt = e;
}
- END_CATCH
}
else
{
bl->overlay_target_info.reqstd_address = addr;
/* No overlay handling: just set the breakpoint. */
- TRY
+ try
{
int val;
bp_excpt
= gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
- CATCH (e, RETURN_MASK_ALL)
+ catch (const gdb_exception &e)
{
bp_excpt = e;
}
- END_CATCH
if (bp_excpt.reason != 0)
fprintf_unfiltered (tmp_error_stream,
if (section_is_mapped (bl->section))
{
/* Yes. This overlay section is mapped into memory. */
- TRY
+ try
{
int val;
if (val)
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
- CATCH (e, RETURN_MASK_ALL)
+ catch (const gdb_exception &e)
{
bp_excpt = e;
}
- END_CATCH
}
else
{
bp_excpt.message ? ":" : ".\n");
if (bp_excpt.message != NULL)
fprintf_unfiltered (tmp_error_stream, "%s.\n",
- bp_excpt.message);
+ bp_excpt.what ());
}
else
{
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d: %s\n",
bl->owner->number,
- bp_excpt.message);
+ bp_excpt.what ());
}
}
return 1;
/* We only want to update locations that are already inserted
and need updating. This is to avoid unwanted insertion during
deletion of breakpoints. */
- if (!bl->inserted || (bl->inserted && !bl->needs_update))
+ if (!bl->inserted || !bl->needs_update)
continue;
switch_to_program_space_and_thread (bl->pspace);
if we aren't attached to any process yet, we should still
insert breakpoints. */
if (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && ptid_equal (inferior_ptid, null_ptid))
+ && inferior_ptid == null_ptid)
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
if we aren't attached to any process yet, we should still
insert breakpoints. */
if (!gdbarch_has_global_breakpoints (target_gdbarch ())
- && ptid_equal (inferior_ptid, null_ptid))
+ && inferior_ptid == null_ptid)
continue;
val = insert_bp_location (bl, &tmp_error_stream, &disabled_breaks,
}
}
-/* Remove breakpoints of process PID. */
+/* Remove breakpoints of inferior INF. */
int
-remove_breakpoints_pid (int pid)
+remove_breakpoints_inf (inferior *inf)
{
struct bp_location *bl, **blp_tmp;
int val;
- struct inferior *inf = find_inferior_pid (pid);
ALL_BP_LOCATIONS (bl, blp_tmp)
{
static void
create_overlay_event_breakpoint (void)
{
- struct objfile *objfile;
const char *const func_name = "_ovly_debug_event";
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data;
ALL_PSPACES (pspace)
{
- struct objfile *objfile;
-
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- int i;
- struct gdbarch *gdbarch;
- struct breakpoint_objfile_data *bp_objfile_data;
-
- gdbarch = get_objfile_arch (objfile);
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ int i;
+ struct gdbarch *gdbarch;
+ struct breakpoint_objfile_data *bp_objfile_data;
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
+ gdbarch = get_objfile_arch (objfile);
- if (!bp_objfile_data->longjmp_searched)
- {
- std::vector<probe *> ret
- = find_probes_in_objfile (objfile, "libc", "longjmp");
+ bp_objfile_data = get_breakpoint_objfile_data (objfile);
- if (!ret.empty ())
- {
- /* We are only interested in checking one element. */
- probe *p = ret[0];
+ if (!bp_objfile_data->longjmp_searched)
+ {
+ std::vector<probe *> ret
+ = find_probes_in_objfile (objfile, "libc", "longjmp");
- if (!p->can_evaluate_arguments ())
- {
- /* We cannot use the probe interface here, because it does
- not know how to evaluate arguments. */
- ret.clear ();
- }
- }
- bp_objfile_data->longjmp_probes = ret;
- bp_objfile_data->longjmp_searched = 1;
- }
+ if (!ret.empty ())
+ {
+ /* We are only interested in checking one element. */
+ probe *p = ret[0];
- if (!bp_objfile_data->longjmp_probes.empty ())
- {
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ if (!p->can_evaluate_arguments ())
+ {
+ /* We cannot use the probe interface here, because it does
+ not know how to evaluate arguments. */
+ ret.clear ();
+ }
+ }
+ bp_objfile_data->longjmp_probes = ret;
+ bp_objfile_data->longjmp_searched = 1;
+ }
- for (probe *p : bp_objfile_data->longjmp_probes)
- {
- struct breakpoint *b;
+ if (!bp_objfile_data->longjmp_probes.empty ())
+ {
+ for (probe *p : bp_objfile_data->longjmp_probes)
+ {
+ struct breakpoint *b;
+
+ b = create_internal_breakpoint (gdbarch,
+ p->get_relocated_address (objfile),
+ bp_longjmp_master,
+ &internal_breakpoint_ops);
+ b->location = new_probe_location ("-probe-stap libc:longjmp");
+ b->enable_state = bp_disabled;
+ }
- b = create_internal_breakpoint (gdbarch,
- p->get_relocated_address (objfile),
- bp_longjmp_master,
- &internal_breakpoint_ops);
- b->location = new_probe_location ("-probe-stap libc:longjmp");
- b->enable_state = bp_disabled;
- }
+ continue;
+ }
+ if (!gdbarch_get_longjmp_target_p (gdbarch))
continue;
- }
- if (!gdbarch_get_longjmp_target_p (gdbarch))
- continue;
-
- for (i = 0; i < NUM_LONGJMP_NAMES; i++)
- {
- struct breakpoint *b;
- const char *func_name;
- CORE_ADDR addr;
- struct explicit_location explicit_loc;
+ for (i = 0; i < NUM_LONGJMP_NAMES; i++)
+ {
+ struct breakpoint *b;
+ const char *func_name;
+ CORE_ADDR addr;
+ struct explicit_location explicit_loc;
- if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
- continue;
+ if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
+ continue;
- func_name = longjmp_names[i];
- if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
- {
- struct bound_minimal_symbol m;
+ func_name = longjmp_names[i];
+ if (bp_objfile_data->longjmp_msym[i].minsym == NULL)
+ {
+ struct bound_minimal_symbol m;
- m = lookup_minimal_symbol_text (func_name, objfile);
- if (m.minsym == NULL)
- {
- /* Prevent future lookups in this objfile. */
- bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
- continue;
- }
- bp_objfile_data->longjmp_msym[i] = m;
- }
+ m = lookup_minimal_symbol_text (func_name, objfile);
+ if (m.minsym == NULL)
+ {
+ /* Prevent future lookups in this objfile. */
+ bp_objfile_data->longjmp_msym[i].minsym = &msym_not_found;
+ continue;
+ }
+ bp_objfile_data->longjmp_msym[i] = m;
+ }
- addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
- b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
- &internal_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
- b->enable_state = bp_disabled;
- }
- }
+ addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+ b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master,
+ &internal_breakpoint_ops);
+ initialize_explicit_location (&explicit_loc);
+ explicit_loc.function_name = ASTRDUP (func_name);
+ b->location = new_explicit_location (&explicit_loc);
+ b->enable_state = bp_disabled;
+ }
+ }
}
}
ALL_PSPACES (pspace)
{
- struct objfile *objfile;
CORE_ADDR addr;
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- struct breakpoint *b;
- struct breakpoint_objfile_data *bp_objfile_data;
- struct explicit_location explicit_loc;
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ struct breakpoint *b;
+ struct breakpoint_objfile_data *bp_objfile_data;
+ struct explicit_location explicit_loc;
- bp_objfile_data = get_breakpoint_objfile_data (objfile);
+ bp_objfile_data = get_breakpoint_objfile_data (objfile);
- if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
- continue;
+ if (msym_not_found_p (bp_objfile_data->terminate_msym.minsym))
+ continue;
- if (bp_objfile_data->terminate_msym.minsym == NULL)
- {
- struct bound_minimal_symbol m;
+ if (bp_objfile_data->terminate_msym.minsym == NULL)
+ {
+ struct bound_minimal_symbol m;
- m = lookup_minimal_symbol (func_name, NULL, objfile);
- if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
- && MSYMBOL_TYPE (m.minsym) != mst_file_text))
- {
- /* Prevent future lookups in this objfile. */
- bp_objfile_data->terminate_msym.minsym = &msym_not_found;
- continue;
- }
- bp_objfile_data->terminate_msym = m;
- }
+ m = lookup_minimal_symbol (func_name, NULL, objfile);
+ if (m.minsym == NULL || (MSYMBOL_TYPE (m.minsym) != mst_text
+ && MSYMBOL_TYPE (m.minsym) != mst_file_text))
+ {
+ /* Prevent future lookups in this objfile. */
+ bp_objfile_data->terminate_msym.minsym = &msym_not_found;
+ continue;
+ }
+ bp_objfile_data->terminate_msym = m;
+ }
- addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
- b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
- bp_std_terminate_master,
- &internal_breakpoint_ops);
- initialize_explicit_location (&explicit_loc);
- explicit_loc.function_name = ASTRDUP (func_name);
- b->location = new_explicit_location (&explicit_loc);
- b->enable_state = bp_disabled;
- }
+ addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
+ b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
+ bp_std_terminate_master,
+ &internal_breakpoint_ops);
+ initialize_explicit_location (&explicit_loc);
+ explicit_loc.function_name = ASTRDUP (func_name);
+ b->location = new_explicit_location (&explicit_loc);
+ b->enable_state = bp_disabled;
+ }
}
}
static void
create_exception_master_breakpoint (void)
{
- struct objfile *objfile;
const char *const func_name = "_Unwind_DebugHook";
- ALL_OBJFILES (objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
struct breakpoint *b;
struct gdbarch *gdbarch;
if (!bp_objfile_data->exception_probes.empty ())
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ gdbarch = get_objfile_arch (objfile);
for (probe *p : bp_objfile_data->exception_probes)
{
- struct breakpoint *b;
-
b = create_internal_breakpoint (gdbarch,
p->get_relocated_address (objfile),
bp_exception_master,
}
addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
- addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, target_stack);
+ addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
+ current_top_target ());
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
&internal_breakpoint_ops);
initialize_explicit_location (&explicit_loc);
scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
struct inferior *inf = current_inferior ();
- if (ptid_get_pid (ptid) == ptid_get_pid (inferior_ptid))
+ if (ptid.pid () == inferior_ptid.pid ())
error (_("Cannot detach breakpoints of inferior_ptid"));
/* Set inferior_ptid; remove_breakpoint_1 uses this global. */
breakpoint_init_inferior (enum inf_context context)
{
struct breakpoint *b, *b_tmp;
- struct bp_location *bl;
- int ix;
struct program_space *pspace = current_program_space;
/* If breakpoint locations are shared across processes, then there's
}
/* Get rid of the moribund locations. */
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, bl); ++ix)
+ for (bp_location *bl : moribund_locations)
decref_bp_location (&bl);
- VEC_free (bp_location_p, moribund_locations);
+ moribund_locations.clear ();
}
/* These functions concern about actual breakpoints inserted in the
int
moribund_breakpoint_here_p (const address_space *aspace, CORE_ADDR pc)
{
- struct bp_location *loc;
- int ix;
-
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ for (bp_location *loc : moribund_locations)
if (breakpoint_location_address_match (loc, aspace, pc))
return 1;
void
bpstat_clear_actions (void)
{
- struct thread_info *tp;
bpstat bs;
- if (ptid_equal (inferior_ptid, null_ptid))
- return;
-
- tp = find_thread_ptid (inferior_ptid);
- if (tp == NULL)
+ if (inferior_ptid == null_ptid)
return;
+ thread_info *tp = inferior_thread ();
for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
{
bs->commands = NULL;
static void
breakpoint_about_to_proceed (void)
{
- if (!ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid != null_ptid)
{
struct thread_info *tp = inferior_thread ();
return again;
}
+/* Helper for bpstat_do_actions. Get the current thread, if there's
+ one, is alive and has execution. Return NULL otherwise. */
+
+static thread_info *
+get_bpstat_thread ()
+{
+ if (inferior_ptid == null_ptid || !target_has_execution)
+ return NULL;
+
+ thread_info *tp = inferior_thread ();
+ if (tp->state == THREAD_EXITED || tp->executing)
+ return NULL;
+ return tp;
+}
+
void
bpstat_do_actions (void)
{
- struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
+ auto cleanup_if_error = make_scope_exit (bpstat_clear_actions);
+ thread_info *tp;
/* Do any commands attached to breakpoint we are stopped at. */
- while (!ptid_equal (inferior_ptid, null_ptid)
- && target_has_execution
- && !is_exited (inferior_ptid)
- && !is_executing (inferior_ptid))
- /* Since in sync mode, bpstat_do_actions may resume the inferior,
- and only return when it is stopped at the next breakpoint, we
- keep doing breakpoint actions until it returns false to
- indicate the inferior was not resumed. */
- if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
- break;
+ while ((tp = get_bpstat_thread ()) != NULL)
+ {
+ /* Since in sync mode, bpstat_do_actions may resume the
+ inferior, and only return when it is stopped at the next
+ breakpoint, we keep doing breakpoint actions until it returns
+ false to indicate the inferior was not resumed. */
+ if (!bpstat_do_actions_1 (&tp->control.stop_bpstat))
+ break;
+ }
- discard_cleanups (cleanup_if_error);
+ cleanup_if_error.release ();
}
/* Print out the (old or new) value associated with a watchpoint. */
print_solib_event (int is_catchpoint)
{
bool any_deleted = !current_program_space->deleted_solibs.empty ();
- int any_added
- = !VEC_empty (so_list_ptr, current_program_space->added_solibs);
+ bool any_added = !current_program_space->added_solibs.empty ();
if (!is_catchpoint)
{
if (any_added)
{
- struct so_list *iter;
- int ix;
-
current_uiout->text (_(" Inferior loaded "));
ui_out_emit_list list_emitter (current_uiout, "added");
- for (ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
+ bool first = true;
+ for (so_list *iter : current_program_space->added_solibs)
{
- if (ix > 0)
+ if (!first)
current_uiout->text (" ");
+ first = false;
current_uiout->field_string ("library", iter->so_name);
current_uiout->text ("\n");
}
return 0;
}
- if (!target_stopped_data_address (target_stack, &addr))
+ if (!target_stopped_data_address (current_top_target (), &addr))
{
/* We were stopped by a watchpoint, but we don't know where.
Mark all watchpoints as unknown. */
}
}
/* Exact match not required. Within range is sufficient. */
- else if (target_watchpoint_addr_within_range (target_stack,
+ else if (target_watchpoint_addr_within_range (current_top_target (),
addr, loc->address,
loc->length))
{
{
wp_check_result e;
- TRY
+ try
{
e = watchpoint_check (bs);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error evaluating expression "
watchpoint_del_at_next_stop (b);
e = WP_DELETED;
}
- END_CATCH
switch (e)
{
breakpoint, set BS->stop to 0. */
static void
-bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
+bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread)
{
const struct bp_location *bl;
struct breakpoint *b;
/* If this is a thread/task-specific breakpoint, don't waste cpu
evaluating the condition if this isn't the specified
thread/task. */
- if ((b->thread != -1 && b->thread != ptid_to_global_thread_id (ptid))
- || (b->task != 0 && b->task != ada_get_task_number (ptid)))
-
+ if ((b->thread != -1 && b->thread != thread->global_num)
+ || (b->task != 0 && b->task != ada_get_task_number (thread)))
{
bs->stop = 0;
return;
}
if (within_current_scope)
{
- TRY
+ try
{
condition_result = breakpoint_cond_eval (cond);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error in testing breakpoint condition:\n");
}
- END_CATCH
}
else
{
&& !target_supports_stopped_by_hw_breakpoint ()));
}
-
-/* Get a bpstat associated with having just stopped at address
- BP_ADDR in thread PTID.
-
- Determine whether we stopped at a breakpoint, etc, or whether we
- don't understand this stop. Result is a chain of bpstat's such
- that:
-
- if we don't understand the stop, the result is a null pointer.
-
- if we understand why we stopped, the result is not null.
-
- Each element of the chain refers to a particular breakpoint or
- watchpoint at which we have stopped. (We may have stopped for
- several reasons concurrently.)
-
- Each element of the chain has valid next, breakpoint_at,
- commands, FIXME??? fields. */
+/* See breakpoint.h. */
bpstat
-bpstat_stop_status (const address_space *aspace,
- CORE_ADDR bp_addr, ptid_t ptid,
+build_bpstat_chain (const address_space *aspace, CORE_ADDR bp_addr,
const struct target_waitstatus *ws)
{
- struct breakpoint *b = NULL;
- struct bp_location *bl;
- struct bp_location *loc;
- /* First item of allocated bpstat's. */
+ struct breakpoint *b;
bpstat bs_head = NULL, *bs_link = &bs_head;
- /* Pointer to the last thing in the chain currently. */
- bpstat bs;
- int ix;
- int need_remove_insert;
- int removed_any;
-
- /* First, build the bpstat chain with locations that explain a
- target stop, while being careful to not set the target running,
- as that may invalidate locations (in particular watchpoint
- locations are recreated). Resuming will happen here with
- breakpoint conditions or watchpoint expressions that include
- inferior function calls. */
ALL_BREAKPOINTS (b)
{
if (!breakpoint_enabled (b))
continue;
- for (bl = b->loc; bl != NULL; bl = bl->next)
+ for (bp_location *bl = b->loc; bl != NULL; bl = bl->next)
{
/* For hardware watchpoints, we look only at the first
location. The watchpoint_check function will work on the
/* Come here if it's a watchpoint, or if the break address
matches. */
- bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
- explain stop. */
+ bpstat bs = new bpstats (bl, &bs_link); /* Alloc a bpstat to
+ explain stop. */
/* Assume we stop. Should we find a watchpoint that is not
actually triggered, or if the condition of the breakpoint
if (!target_supports_stopped_by_sw_breakpoint ()
|| !target_supports_stopped_by_hw_breakpoint ())
{
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ for (bp_location *loc : moribund_locations)
{
if (breakpoint_location_address_match (loc, aspace, bp_addr)
&& need_moribund_for_location_type (loc))
{
- bs = new bpstats (loc, &bs_link);
+ bpstat bs = new bpstats (loc, &bs_link);
/* For hits of moribund locations, we should just proceed. */
bs->stop = 0;
bs->print = 0;
}
}
+ return bs_head;
+}
+
+/* See breakpoint.h. */
+
+bpstat
+bpstat_stop_status (const address_space *aspace,
+ CORE_ADDR bp_addr, thread_info *thread,
+ const struct target_waitstatus *ws,
+ bpstat stop_chain)
+{
+ struct breakpoint *b = NULL;
+ /* First item of allocated bpstat's. */
+ bpstat bs_head = stop_chain;
+ bpstat bs;
+ int need_remove_insert;
+ int removed_any;
+
+ /* First, build the bpstat chain with locations that explain a
+ target stop, while being careful to not set the target running,
+ as that may invalidate locations (in particular watchpoint
+ locations are recreated). Resuming will happen here with
+ breakpoint conditions or watchpoint expressions that include
+ inferior function calls. */
+ if (bs_head == NULL)
+ bs_head = build_bpstat_chain (aspace, bp_addr, ws);
+
/* A bit of special processing for shlib breakpoints. We need to
process solib loading here, so that the lists of loaded and
unloaded libraries are correct before we handle "catch load" and
b->ops->check_status (bs);
if (bs->stop)
{
- bpstat_check_breakpoint_conditions (bs, ptid);
+ bpstat_check_breakpoint_conditions (bs, thread);
if (bs->stop)
{
{
const struct symbol *sym = loc->symbol;
- if (sym == NULL)
- sym = find_pc_sect_function (loc->address, loc->section);
-
if (sym)
{
uiout->text ("in ");
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+ uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
+ ui_out_style_kind::FUNCTION);
uiout->text (" ");
uiout->wrap_hint (wrap_indent_at_field (uiout, "what"));
uiout->text ("at ");
}
uiout->field_string ("file",
- symtab_to_filename_for_display (loc->symtab));
+ symtab_to_filename_for_display (loc->symtab),
+ ui_out_style_kind::FILE);
uiout->text (":");
if (uiout->is_mi_like_p ())
/* 1 */
annotate_field (0);
if (part_of_multiple)
- {
- char *formatted;
- formatted = xstrprintf ("%d.%d", b->number, loc_number);
- uiout->field_string ("number", formatted);
- xfree (formatted);
- }
+ uiout->field_fmt ("number", "%d.%d", b->number, loc_number);
else
- {
- uiout->field_int ("number", b->number);
- }
+ uiout->field_int ("number", b->number);
/* 2 */
annotate_field (1);
else
uiout->field_string ("disp", bpdisp_text (b->disposition));
-
/* 4 */
annotate_field (3);
if (part_of_multiple)
uiout->field_string ("enabled", loc->enabled ? "y" : "n");
else
uiout->field_fmt ("enabled", "%c", bpenables[(int) b->enable_state]);
- uiout->spaces (2);
-
/* 5 and 6 */
if (b->ops != NULL && b->ops->print_one != NULL)
{
if (loc != NULL && !header_of_multiple)
{
- struct inferior *inf;
std::vector<int> inf_nums;
int mi_only = 1;
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_inferiors ())
{
if (inf->pspace == loc->pspace)
inf_nums.push_back (inf->num);
int allflag)
{
struct ui_out *uiout = current_uiout;
+ bool use_fixed_output = mi_multi_location_breakpoint_output_fixed (uiout);
- {
- ui_out_emit_tuple tuple_emitter (uiout, "bkpt");
+ gdb::optional<ui_out_emit_tuple> bkpt_tuple_emitter (gdb::in_place, uiout, "bkpt");
+ print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
- print_one_breakpoint_location (b, NULL, 0, last_loc, allflag);
- }
+ /* The mi2 broken format: the main breakpoint tuple ends here, the locations
+ are outside. */
+ if (!use_fixed_output)
+ bkpt_tuple_emitter.reset ();
/* If this breakpoint has custom print function,
it's already printed. Otherwise, print individual
&& !is_hardware_watchpoint (b)
&& (b->loc->next || !b->loc->enabled))
{
- struct bp_location *loc;
- int n = 1;
+ gdb::optional<ui_out_emit_list> locations_list;
- for (loc = b->loc; loc; loc = loc->next, ++n)
+ /* For MI version <= 2, keep the behavior where GDB outputs an invalid
+ MI record. For later versions, place breakpoint locations in a
+ list. */
+ if (uiout->is_mi_like_p () && use_fixed_output)
+ locations_list.emplace (uiout, "locations");
+
+ int n = 1;
+ for (bp_location *loc = b->loc; loc != NULL; loc = loc->next, ++n)
{
- ui_out_emit_tuple tuple_emitter (uiout, NULL);
+ ui_out_emit_tuple loc_tuple_emitter (uiout, NULL);
print_one_breakpoint_location (b, loc, n, last_loc, allflag);
}
}
: ((others == 1) ? " and" : ""));
}
printf_filtered (_("also set at pc "));
- fputs_filtered (paddress (gdbarch, pc), gdb_stdout);
+ fputs_styled (paddress (gdbarch, pc), address_style.style (), gdb_stdout);
printf_filtered (".\n");
}
}
}
}
-bp_location::bp_location (const bp_location_ops *ops, breakpoint *owner)
+bp_location::bp_location (breakpoint *owner)
{
bp_location *loc = this;
- gdb_assert (ops != NULL);
-
- loc->ops = ops;
loc->owner = owner;
loc->cond_bytecode = NULL;
loc->shlib_disabled = 0;
static void
free_bp_location (struct bp_location *loc)
{
- loc->ops->dtor (loc);
delete loc;
}
new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
&momentary_breakpoint_ops,
1);
- new_b->thread = ptid_to_global_thread_id (inferior_ptid);
+ new_b->thread = inferior_thread ()->global_num;
/* Link NEW_B into the chain of RETVAL breakpoints. */
|| frame_find_by_id (dummy_b->frame_id) != NULL)
continue;
- dummy_frame_discard (dummy_b->frame_id, tp->ptid);
+ dummy_frame_discard (dummy_b->frame_id, tp);
while (b->related_breakpoint != b)
{
static int
insert_catch_fork (struct bp_location *bl)
{
- return target_insert_fork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_insert_fork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "remove" breakpoint_ops method for fork
static int
remove_catch_fork (struct bp_location *bl, enum remove_bp_reason reason)
{
- return target_remove_fork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_remove_fork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "breakpoint_hit" breakpoint_ops method for fork
}
uiout->field_int ("bkptno", b->number);
uiout->text (" (forked process ");
- uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("newpid", c->forked_inferior_pid.pid ());
uiout->text ("), ");
return PRINT_SRC_AND_LOC;
}
uiout->field_skip ("addr");
annotate_field (5);
uiout->text ("fork");
- if (!ptid_equal (c->forked_inferior_pid, null_ptid))
+ if (c->forked_inferior_pid != null_ptid)
{
uiout->text (", process ");
- uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("what", c->forked_inferior_pid.pid ());
uiout->spaces (1);
}
static int
insert_catch_vfork (struct bp_location *bl)
{
- return target_insert_vfork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_insert_vfork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "remove" breakpoint_ops method for vfork
static int
remove_catch_vfork (struct bp_location *bl, enum remove_bp_reason reason)
{
- return target_remove_vfork_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_remove_vfork_catchpoint (inferior_ptid.pid ());
}
/* Implement the "breakpoint_hit" breakpoint_ops method for vfork
}
uiout->field_int ("bkptno", b->number);
uiout->text (" (vforked process ");
- uiout->field_int ("newpid", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("newpid", c->forked_inferior_pid.pid ());
uiout->text ("), ");
return PRINT_SRC_AND_LOC;
}
uiout->field_skip ("addr");
annotate_field (5);
uiout->text ("vfork");
- if (!ptid_equal (c->forked_inferior_pid, null_ptid))
+ if (c->forked_inferior_pid != null_ptid)
{
uiout->text (", process ");
- uiout->field_int ("what", ptid_get_pid (c->forked_inferior_pid));
+ uiout->field_int ("what", c->forked_inferior_pid.pid ());
uiout->spaces (1);
}
if (self->is_load)
{
- struct so_list *iter;
-
- for (int ix = 0;
- VEC_iterate (so_list_ptr, current_program_space->added_solibs,
- ix, iter);
- ++ix)
+ for (so_list *iter : current_program_space->added_solibs)
{
if (!self->regex
|| self->compiled->exec (iter->so_name, 0, NULL, 0) == 0)
struct solib_catchpoint *self = (struct solib_catchpoint *) b;
struct value_print_options opts;
struct ui_out *uiout = current_uiout;
- char *msg;
get_user_print_options (&opts);
/* Field 4, the address, is omitted (which makes the columns not
uiout->field_skip ("addr");
}
+ std::string msg;
annotate_field (5);
if (self->is_load)
{
if (self->regex)
- msg = xstrprintf (_("load of library matching %s"), self->regex);
+ msg = string_printf (_("load of library matching %s"), self->regex);
else
- msg = xstrdup (_("load of library"));
+ msg = _("load of library");
}
else
{
if (self->regex)
- msg = xstrprintf (_("unload of library matching %s"), self->regex);
+ msg = string_printf (_("unload of library matching %s"), self->regex);
else
- msg = xstrdup (_("unload of library"));
+ msg = _("unload of library");
}
uiout->field_string ("what", msg);
- xfree (msg);
if (uiout->is_mi_like_p ())
uiout->field_string ("catch-type", self->is_load ? "load" : "unload");
static int
insert_catch_exec (struct bp_location *bl)
{
- return target_insert_exec_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_insert_exec_catchpoint (inferior_ptid.pid ());
}
static int
remove_catch_exec (struct bp_location *bl, enum remove_bp_reason reason)
{
- return target_remove_exec_catchpoint (ptid_get_pid (inferior_ptid));
+ return target_remove_exec_catchpoint (inferior_ptid.pid ());
}
static int
b->disposition = disp_donttouch;
b->frame_id = frame_id;
- /* If we're debugging a multi-threaded program, then we want
- momentary breakpoints to be active in only a single thread of
- control. */
- if (in_thread_list (inferior_ptid))
- b->thread = ptid_to_global_thread_id (inferior_ptid);
+ b->thread = inferior_thread ()->global_num;
update_global_location_list_nothrow (UGLL_MAY_INSERT);
unsigned flags)
{
struct linespec_result canonical;
- struct cleanup *bkpt_chain = NULL;
int pending = 0;
int task = 0;
int prev_bkpt_count = breakpoint_count;
if (extra_string != NULL && *extra_string == '\0')
extra_string = NULL;
- TRY
+ try
{
ops->create_sals_from_location (location, &canonical, type_wanted);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
/* If caller is interested in rc value from parse, set
value. */
error. */
if (pending_break_support == AUTO_BOOLEAN_FALSE)
- throw_exception (e);
+ throw;
exception_print (gdb_stderr, e);
pending = 1;
}
else
- throw_exception (e);
+ throw;
}
- END_CATCH
if (!pending && canonical.lsals.empty ())
return 0;
- /* ----------------------------- SNIP -----------------------------
- Anything added to the cleanup chain beyond this point is assumed
- to be part of a breakpoint. If the breakpoint create succeeds
- then the memory is not reclaimed. */
- bkpt_chain = make_cleanup (null_cleanup, 0);
-
/* Resolve all line numbers to PC's and verify that the addresses
are ok for the target. */
if (!pending)
prev_breakpoint_count = prev_bkpt_count;
}
- /* That's it. Discard the cleanups for data inserted into the
- breakpoint. */
- discard_cleanups (bkpt_chain);
-
- /* error call may happen here - have BKPT_CHAIN already discarded. */
update_global_location_list (UGLL_MAY_INSERT);
return 1;
}
if (badInput)
- printf_filtered (_("Usage: stop at <line>\n"));
+ printf_filtered (_("Usage: stop at LINE\n"));
else
break_command_1 (arg, 0, from_tty);
}
{
struct breakpoint *scope_breakpoint = NULL;
const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
- struct value *mark, *result;
+ struct value *result;
int saved_bitpos = 0, saved_bitsize = 0;
const char *exp_start = NULL;
const char *exp_end = NULL;
/* Parse the rest of the arguments. From here on out, everything
is in terms of a newly allocated string instead of the original
ARG. */
- innermost_block.reset ();
std::string expression (arg, exp_end - arg);
exp_start = arg = expression.c_str ();
- expression_up exp = parse_exp_1 (&arg, 0, 0, 0);
+ innermost_block_tracker tracker;
+ expression_up exp = parse_exp_1 (&arg, 0, 0, 0, &tracker);
exp_end = arg;
/* Remove trailing whitespace from the expression before saving it.
This makes the eventual display of the expression string a bit
error (_("Cannot watch constant value `%.*s'."), len, exp_start);
}
- exp_valid_block = innermost_block.block ();
- mark = value_mark ();
+ exp_valid_block = tracker.block ();
+ struct value *mark = value_mark ();
struct value *val_as_value = nullptr;
fetch_subexp_value (exp.get (), &pc, &val_as_value, &result, NULL,
just_location);
toklen = end_tok - tok;
if (toklen >= 1 && strncmp (tok, "if", toklen) == 0)
{
- innermost_block.reset ();
tok = cond_start = end_tok + 1;
- parse_exp_1 (&tok, 0, 0, 0);
+ innermost_block_tracker if_tracker;
+ parse_exp_1 (&tok, 0, 0, 0, &if_tracker);
/* The watchpoint expression may not be local, but the condition
may still be. E.g.: `watch global if local > 0'. */
- cond_exp_valid_block = innermost_block.block ();
+ cond_exp_valid_block = if_tracker.block ();
cond_end = tok;
}
in infcmd.c. Here because it uses the mechanisms of
breakpoints. */
-struct until_break_fsm
+struct until_break_fsm : public thread_fsm
{
- /* The base class. */
- struct thread_fsm thread_fsm;
-
- /* The thread that as current when the command was executed. */
+ /* The thread that was current when the command was executed. */
int thread;
/* The breakpoint set at the destination location. */
- struct breakpoint *location_breakpoint;
+ breakpoint_up location_breakpoint;
/* Breakpoint set at the return address in the caller frame. May be
NULL. */
- struct breakpoint *caller_breakpoint;
-};
-
-static void until_break_fsm_clean_up (struct thread_fsm *self,
- struct thread_info *thread);
-static int until_break_fsm_should_stop (struct thread_fsm *self,
- struct thread_info *thread);
-static enum async_reply_reason
- until_break_fsm_async_reply_reason (struct thread_fsm *self);
+ breakpoint_up caller_breakpoint;
-/* until_break_fsm's vtable. */
+ until_break_fsm (struct interp *cmd_interp, int thread,
+ breakpoint_up &&location_breakpoint,
+ breakpoint_up &&caller_breakpoint)
+ : thread_fsm (cmd_interp),
+ thread (thread),
+ location_breakpoint (std::move (location_breakpoint)),
+ caller_breakpoint (std::move (caller_breakpoint))
+ {
+ }
-static struct thread_fsm_ops until_break_fsm_ops =
-{
- NULL, /* dtor */
- until_break_fsm_clean_up,
- until_break_fsm_should_stop,
- NULL, /* return_value */
- until_break_fsm_async_reply_reason,
+ void clean_up (struct thread_info *thread) override;
+ bool should_stop (struct thread_info *thread) override;
+ enum async_reply_reason do_async_reply_reason () override;
};
-/* Allocate a new until_break_command_fsm. */
-
-static struct until_break_fsm *
-new_until_break_fsm (struct interp *cmd_interp, int thread,
- breakpoint_up &&location_breakpoint,
- breakpoint_up &&caller_breakpoint)
-{
- struct until_break_fsm *sm;
-
- sm = XCNEW (struct until_break_fsm);
- thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops, cmd_interp);
-
- sm->thread = thread;
- sm->location_breakpoint = location_breakpoint.release ();
- sm->caller_breakpoint = caller_breakpoint.release ();
-
- return sm;
-}
-
/* Implementation of the 'should_stop' FSM method for the
until(location)/advance commands. */
-static int
-until_break_fsm_should_stop (struct thread_fsm *self,
- struct thread_info *tp)
+bool
+until_break_fsm::should_stop (struct thread_info *tp)
{
- struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
if (bpstat_find_breakpoint (tp->control.stop_bpstat,
- sm->location_breakpoint) != NULL
- || (sm->caller_breakpoint != NULL
+ location_breakpoint.get ()) != NULL
+ || (caller_breakpoint != NULL
&& bpstat_find_breakpoint (tp->control.stop_bpstat,
- sm->caller_breakpoint) != NULL))
- thread_fsm_set_finished (self);
+ caller_breakpoint.get ()) != NULL))
+ set_finished ();
- return 1;
+ return true;
}
/* Implementation of the 'clean_up' FSM method for the
until(location)/advance commands. */
-static void
-until_break_fsm_clean_up (struct thread_fsm *self,
- struct thread_info *thread)
+void
+until_break_fsm::clean_up (struct thread_info *)
{
- struct until_break_fsm *sm = (struct until_break_fsm *) self;
-
/* Clean up our temporary breakpoints. */
- if (sm->location_breakpoint != NULL)
- {
- delete_breakpoint (sm->location_breakpoint);
- sm->location_breakpoint = NULL;
- }
- if (sm->caller_breakpoint != NULL)
- {
- delete_breakpoint (sm->caller_breakpoint);
- sm->caller_breakpoint = NULL;
- }
- delete_longjmp_breakpoint (sm->thread);
+ location_breakpoint.reset ();
+ caller_breakpoint.reset ();
+ delete_longjmp_breakpoint (thread);
}
/* Implementation of the 'async_reply_reason' FSM method for the
until(location)/advance commands. */
-static enum async_reply_reason
-until_break_fsm_async_reply_reason (struct thread_fsm *self)
+enum async_reply_reason
+until_break_fsm::do_async_reply_reason ()
{
return EXEC_ASYNC_LOCATION_REACHED;
}
struct gdbarch *frame_gdbarch;
struct frame_id stack_frame_id;
struct frame_id caller_frame_id;
- struct cleanup *old_chain;
int thread;
struct thread_info *tp;
- struct until_break_fsm *sm;
clear_proceed_status (0);
tp = inferior_thread ();
thread = tp->global_num;
- old_chain = make_cleanup (null_cleanup, NULL);
-
/* Note linespec handling above invalidates the frame chain.
Installing a breakpoint also invalidates the frame chain (as it
may need to switch threads), so do any frame handling before
one. */
breakpoint_up caller_breakpoint;
+
+ gdb::optional<delete_longjmp_breakpoint_cleanup> lj_deleter;
+
if (frame_id_p (caller_frame_id))
{
struct symtab_and_line sal2;
bp_until);
set_longjmp_breakpoint (tp, caller_frame_id);
- make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
+ lj_deleter.emplace (thread);
}
/* set_momentary_breakpoint could invalidate FRAME. */
location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
stack_frame_id, bp_until);
- sm = new_until_break_fsm (command_interp (), tp->global_num,
- std::move (location_breakpoint),
- std::move (caller_breakpoint));
- tp->thread_fsm = &sm->thread_fsm;
+ tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num,
+ std::move (location_breakpoint),
+ std::move (caller_breakpoint));
- discard_cleanups (old_chain);
+ if (lj_deleter)
+ lj_deleter->release ();
proceed (-1, GDB_SIGNAL_DEFAULT);
}
/* Remove duplicates from the vec. */
std::sort (found.begin (), found.end (),
- [] (const breakpoint *a, const breakpoint *b)
+ [] (const breakpoint *bp_a, const breakpoint *bp_b)
{
- return compare_breakpoints (a, b) < 0;
+ return compare_breakpoints (bp_a, bp_b) < 0;
});
found.erase (std::unique (found.begin (), found.end (),
- [] (const breakpoint *a, const breakpoint *b)
+ [] (const breakpoint *bp_a, const breakpoint *bp_b)
{
- return compare_breakpoints (a, b) == 0;
+ return compare_breakpoints (bp_a, bp_b) == 0;
}),
found.end ());
old_loc->events_till_retirement = 3 * (thread_count () + 1);
old_loc->owner = NULL;
- VEC_safe_push (bp_location_p, moribund_locations, old_loc);
+ moribund_locations.push_back (old_loc);
}
else
{
void
breakpoint_retire_moribund (void)
{
- struct bp_location *loc;
- int ix;
-
- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
- if (--(loc->events_till_retirement) == 0)
- {
- decref_bp_location (&loc);
- VEC_unordered_remove (bp_location_p, moribund_locations, ix);
- --ix;
- }
+ for (int ix = 0; ix < moribund_locations.size (); ++ix)
+ {
+ struct bp_location *loc = moribund_locations[ix];
+ if (--(loc->events_till_retirement) == 0)
+ {
+ decref_bp_location (&loc);
+ unordered_remove (moribund_locations, ix);
+ --ix;
+ }
+ }
}
static void
update_global_location_list_nothrow (enum ugll_insert_mode insert_mode)
{
- TRY
+ try
{
update_global_location_list (insert_mode);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
}
- END_CATCH
}
/* Clear BKP from a BPS. */
if (opts.addressprint || b->loc->symtab == NULL)
{
printf_filtered (" at ");
- fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
- gdb_stdout);
+ fputs_styled (paddress (b->loc->gdbarch, b->loc->address),
+ address_style.style (),
+ gdb_stdout);
}
if (b->loc->symtab != NULL)
{
/* If there is a single location, we can print the location
more nicely. */
if (b->loc->next == NULL)
- printf_filtered (": file %s, line %d.",
- symtab_to_filename_for_display (b->loc->symtab),
- b->loc->line_number);
+ {
+ puts_filtered (": file ");
+ fputs_styled (symtab_to_filename_for_display (b->loc->symtab),
+ file_name_style.style (),
+ gdb_stdout);
+ printf_filtered (", line %d.",
+ b->loc->line_number);
+ }
else
/* This is not ideal, but each location may have a
different file name, and this at least reflects the
}
}
-/* Default bp_location_ops methods. */
-
-static void
-bp_location_dtor (struct bp_location *self)
+bp_location::~bp_location ()
{
- xfree (self->function_name);
+ xfree (function_name);
}
-static const struct bp_location_ops bp_location_ops =
-{
- bp_location_dtor
-};
-
/* Destructor for the breakpoint base class. */
breakpoint::~breakpoint ()
static struct bp_location *
base_breakpoint_allocate_location (struct breakpoint *self)
{
- return new bp_location (&bp_location_ops, self);
+ return new bp_location (self);
}
static void
}
else
map_breakpoint_numbers
- (arg, [&] (breakpoint *b)
+ (arg, [&] (breakpoint *br)
{
- iterate_over_related_breakpoints (b, delete_breakpoint);
+ iterate_over_related_breakpoints (br, delete_breakpoint);
});
}
uiout->text ("Now in ");
if (sym)
{
- uiout->field_string ("func", SYMBOL_PRINT_NAME (sym));
+ uiout->field_string ("func", SYMBOL_PRINT_NAME (sym),
+ ui_out_style_kind::FUNCTION);
uiout->text (" at ");
}
uiout->field_string ("file",
- symtab_to_filename_for_display (sal2.symtab));
+ symtab_to_filename_for_display (sal2.symtab),
+ ui_out_style_kind::FILE);
uiout->text (":");
if (uiout->is_mi_like_p ())
const char *s;
s = b->cond_string;
- TRY
+ try
{
new_loc->cond = parse_exp_1 (&s, sal.pc,
block_for_pc (sal.pc),
0);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
warning (_("failed to reevaluate condition "
"for breakpoint %d: %s"),
- b->number, e.message);
+ b->number, e.what ());
new_loc->enabled = 0;
}
- END_CATCH
}
if (!sals_end.empty ())
std::vector<symtab_and_line> sals;
- TRY
+ try
{
sals = b->ops->decode_location (b, location, search_pspace);
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
int not_found_and_ok = 0;
happens only when a binary has changed, I don't know
which approach is better. */
b->enable_state = bp_disabled;
- throw_exception (e);
+ throw;
}
}
- END_CATCH
if (exception.reason == 0 || exception.error != NOT_FOUND_ERROR)
{
scoped_restore save_input_radix = make_scoped_restore (&input_radix);
scoped_restore_current_pspace_and_thread restore_pspace_thread;
+ /* breakpoint_re_set_one sets the current_language to the language
+ of the breakpoint it is resetting (see prepare_re_set_context)
+ before re-evaluating the breakpoint's location. This change can
+ unfortunately get undone by accident if the language_mode is set
+ to auto, and we either switch frames, or more likely in this context,
+ we select the current frame.
+
+ We prevent this by temporarily turning the language_mode to
+ language_mode_manual. We restore it once all breakpoints
+ have been reset. */
+ scoped_restore save_language_mode = make_scoped_restore (&language_mode);
+ language_mode = language_mode_manual;
+
/* Note: we must not try to insert locations until after all
breakpoints have been re-set. Otherwise, e.g., when re-setting
breakpoint 1, we'd insert the locations of breakpoint 2, which
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
- TRY
+ try
{
breakpoint_re_set_one (b);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error in re-setting breakpoint %d: ",
b->number);
}
- END_CATCH
}
jit_breakpoint_re_set ();
{
if (b->thread != -1)
{
- if (in_thread_list (inferior_ptid))
- b->thread = ptid_to_global_thread_id (inferior_ptid);
+ b->thread = inferior_thread ()->global_num;
/* We're being called after following a fork. The new fork is
selected as current, and unless this was a vfork will have a
target_disable_tracepoint (loc);
}
update_global_location_list (UGLL_DONT_INSERT);
+
+ gdb::observers::breakpoint_modified.notify (loc->owner);
}
/* Enable or disable a range of breakpoint locations. BP_NUM is the
/* Initialize it just to avoid a GCC false warning. */
enum enable_state orig_enable_state = bp_disabled;
- TRY
+ try
{
struct watchpoint *w = (struct watchpoint *) bpt;
bpt->enable_state = bp_enabled;
update_watchpoint (w, 1 /* reparse */);
}
- CATCH (e, RETURN_MASK_ALL)
+ catch (const gdb_exception &e)
{
bpt->enable_state = orig_enable_state;
exception_fprintf (gdb_stderr, e, _("Cannot enable watchpoint %d: "),
bpt->number);
return;
}
- END_CATCH
}
bpt->enable_state = bp_enabled;
if (next_cmd < this_utp->cmd_strings.size ())
{
- rslt = this_utp->cmd_strings[next_cmd];
+ rslt = this_utp->cmd_strings[next_cmd].get ();
next_cmd++;
}
struct tracepoint *tp;
if (utp->at_string)
- addr_str = utp->at_string;
+ addr_str = utp->at_string.get ();
else
{
/* In the absence of a source location, fall back to raw
current_language);
if (!create_breakpoint (get_current_arch (),
location.get (),
- utp->cond_string, -1, addr_str,
+ utp->cond_string.get (), -1, addr_str,
0 /* parse cond/thread */,
0 /* tempflag */,
utp->type /* type_wanted */,
this_utp = utp;
next_cmd = 0;
- cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
+ cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL);
breakpoint_set_commands (tp, std::move (cmd_list));
}
}
else
map_breakpoint_numbers
- (arg, [&] (breakpoint *b)
+ (arg, [&] (breakpoint *br)
{
- iterate_over_related_breakpoints (b, delete_breakpoint);
+ iterate_over_related_breakpoints (br, delete_breakpoint);
});
}
fp.puts (" commands\n");
current_uiout->redirect (&fp);
- TRY
+ try
{
print_command_lines (current_uiout, tp->commands.get (), 2);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
current_uiout->redirect (NULL);
- throw_exception (ex);
+ throw;
}
- END_CATCH
current_uiout->redirect (NULL);
fp.puts (" end\n");
/* Create a vector of all tracepoints. */
-VEC(breakpoint_p) *
+std::vector<breakpoint *>
all_tracepoints (void)
{
- VEC(breakpoint_p) *tp_vec = 0;
+ std::vector<breakpoint *> tp_vec;
struct breakpoint *tp;
ALL_TRACEPOINTS (tp)
{
- VEC_safe_push (breakpoint_p, tp_vec, tp);
+ tp_vec.push_back (tp);
}
return tp_vec;
static struct cmd_list_element *enablebreaklist = NULL;
+/* See breakpoint.h. */
+
+cmd_list_element *commands_cmd_element = nullptr;
+
void
_initialize_breakpoint (void)
{
Set ignore-count of breakpoint number N to COUNT.\n\
Usage is `ignore N COUNT'."));
- add_com ("commands", class_breakpoint, commands_command, _("\
+ commands_cmd_element = add_com ("commands", class_breakpoint,
+ commands_command, _("\
Set commands to be executed when the given breakpoints are hit.\n\
Give a space-separated breakpoint list as argument after \"commands\".\n\
A list element can be a breakpoint number (e.g. `5') or a range of numbers\n\