/* Target-struct-independent code to start (run) and stop an inferior
process.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved.
This file is part of GDB.
#include "frame.h"
#include "inferior.h"
#include "breakpoint.h"
-#include "gdb_wait.h"
#include "gdbcore.h"
#include "gdbcmd.h"
-#include "cli/cli-script.h"
#include "target.h"
#include "gdbthread.h"
#include "annotate.h"
#include "symfile.h"
#include "top.h"
-#include <signal.h>
#include "inf-loop.h"
#include "regcache.h"
#include "value.h"
#include "language.h"
#include "solib.h"
#include "main.h"
-#include "dictionary.h"
#include "block.h"
#include "mi/mi-common.h"
#include "event-top.h"
#include "inline-frame.h"
#include "jit.h"
#include "tracepoint.h"
-#include "continuations.h"
-#include "interps.h"
#include "skip.h"
#include "probe.h"
#include "objfiles.h"
#include "solist.h"
#include "event-loop.h"
#include "thread-fsm.h"
-#include "common/enum-flags.h"
+#include "gdbsupport/enum-flags.h"
#include "progspace-and-thread.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/gdb_optional.h"
#include "arch-utils.h"
-#include "common/scope-exit.h"
+#include "gdbsupport/scope-exit.h"
+#include "gdbsupport/forward-scope-exit.h"
/* Prototypes for local functions */
/* When set, stop the 'step' command if we enter a function which has
no line number information. The normal behavior is that we step
over such function. */
-int step_stop_if_no_debug = 0;
+bool step_stop_if_no_debug = false;
static void
show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
Exactly which branch is detached depends on 'set follow-fork-mode'
setting. */
-static int detach_fork = 1;
+static bool detach_fork = true;
-int debug_displaced = 0;
+bool debug_displaced = false;
static void
show_debug_displaced (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
/* Support for disabling address space randomization. */
-int disable_randomization = 1;
+bool disable_randomization = true;
static void
show_disable_randomization (struct ui_file *file, int from_tty,
/* User interface for non-stop mode. */
-int non_stop = 0;
-static int non_stop_1 = 0;
+bool non_stop = false;
+static bool non_stop_1 = false;
static void
set_non_stop (const char *args, int from_tty,
non-stop, in which all GDB operations that might affect the
target's execution have been disabled. */
-int observer_mode = 0;
-static int observer_mode_1 = 0;
+bool observer_mode = false;
+static bool observer_mode_1 = false;
static void
set_observer_mode (const char *args, int from_tty,
/* We can insert fast tracepoints in or out of observer mode,
but enable them if we're going into this mode. */
if (observer_mode)
- may_insert_fast_tracepoints = 1;
+ may_insert_fast_tracepoints = true;
may_stop = !observer_mode;
update_target_permissions ();
if (observer_mode)
{
pagination_enabled = 0;
- non_stop = non_stop_1 = 1;
+ non_stop = non_stop_1 = true;
}
if (from_tty)
void
update_observer_mode (void)
{
- int newval;
-
- newval = (!may_insert_breakpoints
- && !may_insert_tracepoints
- && may_insert_fast_tracepoints
- && !may_stop
- && non_stop);
+ bool newval = (!may_insert_breakpoints
+ && !may_insert_tracepoints
+ && may_insert_fast_tracepoints
+ && !may_stop
+ && non_stop);
/* Let the user know if things change. */
if (newval != observer_mode)
/* Tables of how to react to signals; the user sets them. */
-static unsigned char *signal_stop;
-static unsigned char *signal_print;
-static unsigned char *signal_program;
+static unsigned char signal_stop[GDB_SIGNAL_LAST];
+static unsigned char signal_print[GDB_SIGNAL_LAST];
+static unsigned char signal_program[GDB_SIGNAL_LAST];
/* Table of signals that are registered with "catch signal". A
non-zero entry indicates that the signal is caught by some "catch
- signal" command. This has size GDB_SIGNAL_LAST, to accommodate all
- signals. */
-static unsigned char *signal_catch;
+ signal" command. */
+static unsigned char signal_catch[GDB_SIGNAL_LAST];
/* Table of signals that the target may silently handle.
This is automatically determined from the flags above,
and simply cached here. */
-static unsigned char *signal_pass;
+static unsigned char signal_pass[GDB_SIGNAL_LAST];
#define SET_SIGS(nsigs,sigs,flags) \
do { \
void
update_signals_program_target (void)
{
- target_program_signals ((int) GDB_SIGNAL_LAST, signal_program);
+ target_program_signals (signal_program);
}
/* Value to pass to target_resume() to cause all threads to resume. */
Can not resume the parent process over vfork in the foreground while\n\
holding the child stopped. Try \"set detach-on-fork\" or \
\"set schedule-multiple\".\n"));
- /* FIXME output string > 80 columns. */
return 1;
}
fprintf_filtered (gdb_stdlog,
_("[Detaching after %s from child %s]\n"),
has_vforked ? "vfork" : "fork",
- target_pid_to_str (process_ptid));
+ target_pid_to_str (process_ptid).c_str ());
}
}
else
fprintf_filtered (gdb_stdlog,
_("[Detaching after fork from "
"parent %s]\n"),
- target_pid_to_str (process_ptid));
+ target_pid_to_str (process_ptid).c_str ());
}
target_detach (parent_inf, 0);
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: resuming vfork parent thread %s\n",
- target_pid_to_str (thread->ptid));
+ target_pid_to_str (thread->ptid).c_str ());
switch_to_thread (thread);
clear_proceed_status (0);
int resume_parent = -1;
/* This exec or exit marks the end of the shared memory region
- between the parent and the child. If the user wanted to
- detach from the parent, now is the time. */
+ between the parent and the child. Break the bonds. */
+ inferior *vfork_parent = inf->vfork_parent;
+ inf->vfork_parent->vfork_child = NULL;
+ inf->vfork_parent = NULL;
- if (inf->vfork_parent->pending_detach)
+ /* If the user wanted to detach from the parent, now is the
+ time. */
+ if (vfork_parent->pending_detach)
{
struct thread_info *tp;
struct program_space *pspace;
/* follow-fork child, detach-on-fork on. */
- inf->vfork_parent->pending_detach = 0;
+ vfork_parent->pending_detach = 0;
gdb::optional<scoped_restore_exited_inferior>
maybe_restore_inferior;
maybe_restore_thread.emplace ();
/* We're letting loose of the parent. */
- tp = any_live_thread_of_inferior (inf->vfork_parent);
+ tp = any_live_thread_of_inferior (vfork_parent);
switch_to_thread (tp);
/* We're about to detach from the parent, which implicitly
if (print_inferior_events)
{
- const char *pidstr
- = target_pid_to_str (ptid_t (inf->vfork_parent->pid));
+ std::string pidstr
+ = target_pid_to_str (ptid_t (vfork_parent->pid));
target_terminal::ours_for_output ();
{
fprintf_filtered (gdb_stdlog,
_("[Detaching vfork parent %s "
- "after child exec]\n"), pidstr);
+ "after child exec]\n"), pidstr.c_str ());
}
else
{
fprintf_filtered (gdb_stdlog,
_("[Detaching vfork parent %s "
- "after child exit]\n"), pidstr);
+ "after child exit]\n"), pidstr.c_str ());
}
}
- target_detach (inf->vfork_parent, 0);
+ target_detach (vfork_parent, 0);
/* Put it back. */
inf->pspace = pspace;
inf->removable = 1;
set_current_program_space (inf->pspace);
- resume_parent = inf->vfork_parent->pid;
-
- /* Break the bonds. */
- inf->vfork_parent->vfork_child = NULL;
+ resume_parent = vfork_parent->pid;
}
else
{
set_current_program_space (pspace);
inf->removable = 1;
inf->symfile_flags = SYMFILE_NO_READ;
- clone_program_space (pspace, inf->vfork_parent->pspace);
+ clone_program_space (pspace, vfork_parent->pspace);
inf->pspace = pspace;
inf->aspace = pspace->aspace;
- resume_parent = inf->vfork_parent->pid;
- /* Break the bonds. */
- inf->vfork_parent->vfork_child = NULL;
+ resume_parent = vfork_parent->pid;
}
- inf->vfork_parent = NULL;
-
gdb_assert (current_program_space == inf->pspace);
if (non_stop && resume_parent != -1)
/* EXEC_FILE_TARGET is assumed to be non-NULL. */
static void
-follow_exec (ptid_t ptid, char *exec_file_target)
+follow_exec (ptid_t ptid, const char *exec_file_target)
{
struct inferior *inf = current_inferior ();
int pid = ptid.pid ();
ptid_t process_ptid;
+ /* Switch terminal for any messages produced e.g. by
+ breakpoint_re_set. */
+ target_terminal::ours_for_output ();
+
/* This is an exec event that we actually wish to pay attention to.
Refresh our symbol table to the newly exec'd program, remove any
momentary bp's, etc.
And, we DON'T want to call delete_breakpoints() here, since
that may write the bp's "shadow contents" (the instruction
- value that was overwritten witha TRAP instruction). Since
+ value that was overwritten with a TRAP instruction). Since
we now have a new a.out, those shadow contents aren't valid. */
mark_breakpoints_out ();
/* What is this a.out's name? */
process_ptid = ptid_t (pid);
printf_unfiltered (_("%s is executing new program: %s\n"),
- target_pid_to_str (process_ptid),
+ target_pid_to_str (process_ptid).c_str (),
exec_file_target);
/* We've followed the inferior through an exec. Therefore, the
inferior has essentially been killed & reborn. */
- gdb_flush (gdb_stdout);
-
breakpoint_init_inferior (inf_execd);
gdb::unique_xmalloc_ptr<char> exec_file_host
register contents, and memory. We use this in step n1.
- gdbarch_displaced_step_fixup adjusts registers and memory after
- we have successfuly single-stepped the instruction, to yield the
+ we have successfully single-stepped the instruction, to yield the
same effect the instruction would have had if we had executed it
at its original address. We use this in step n3.
displaced->step_closure = NULL;
}
-static void
-displaced_step_clear_cleanup (void *arg)
-{
- struct displaced_step_inferior_state *state
- = (struct displaced_step_inferior_state *) arg;
-
- displaced_step_clear (state);
-}
+/* A cleanup that wraps displaced_step_clear. */
+using displaced_step_clear_cleanup
+ = FORWARD_SCOPE_EXIT (displaced_step_clear);
/* Dump LEN bytes at BUF in hex to FILE, followed by a newline. */
void
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
"displaced: deferring step of %s\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
thread_step_over_chain_enqueue (tp);
return 0;
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog,
"displaced: stepping %s now\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
}
displaced_step_clear (displaced);
displaced->step_original = original;
displaced->step_copy = copy;
- cleanup *ignore_cleanups
- = make_cleanup (displaced_step_clear_cleanup, displaced);
+ {
+ displaced_step_clear_cleanup cleanup (displaced);
- /* Resume execution at the copy. */
- regcache_write_pc (regcache, copy);
+ /* Resume execution at the copy. */
+ regcache_write_pc (regcache, copy);
- discard_cleanups (ignore_cleanups);
+ cleanup.release ();
+ }
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: displaced pc to %s\n",
{
int prepared = -1;
- TRY
+ try
{
prepared = displaced_step_prepare_throw (thread);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
struct displaced_step_inferior_state *displaced_state;
if (ex.error != MEMORY_ERROR
&& ex.error != NOT_SUPPORTED_ERROR)
- throw_exception (ex);
+ throw;
if (debug_infrun)
{
fprintf_unfiltered (gdb_stdlog,
"infrun: disabling displaced stepping: %s\n",
- ex.message);
+ ex.what ());
}
/* Be verbose if "set displaced-stepping" is "on", silent if
if (can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
{
warning (_("disabling displaced stepping: %s"),
- ex.message);
+ ex.what ());
}
/* Disable further displaced stepping attempts. */
= get_displaced_stepping_state (thread->inf);
displaced_state->failed_before = 1;
}
- END_CATCH
return prepared;
}
displaced->step_saved_copy.data (), len);
if (debug_displaced)
fprintf_unfiltered (gdb_stdlog, "displaced: restored %s %s\n",
- target_pid_to_str (ptid),
+ target_pid_to_str (ptid).c_str (),
paddress (displaced->step_gdbarch,
displaced->step_copy));
}
static int
displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
{
- struct cleanup *old_cleanups;
struct displaced_step_inferior_state *displaced
= get_displaced_stepping_state (event_thread->inf);
int ret;
if (displaced->step_thread != event_thread)
return 0;
- old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
+ displaced_step_clear_cleanup cleanup (displaced);
displaced_step_restore (displaced, displaced->step_thread->ptid);
ret = -1;
}
- do_cleanups (old_cleanups);
-
- displaced->step_thread = nullptr;
-
return ret;
}
internal_error (__FILE__, __LINE__,
"[%s] has inconsistent state: "
"trap_expected=%d, resumed=%d, executing=%d\n",
- target_pid_to_str (tp->ptid),
+ target_pid_to_str (tp->ptid).c_str (),
tp->control.trap_expected,
tp->resumed,
tp->executing);
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: resuming [%s] for step-over\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
/* keep_going_pass_signal skips the step-over if the breakpoint
is no longer inserted. In all-stop, we want to keep looking
/* True if execution commands resume all threads of all processes by
default; otherwise, resume only threads of the current inferior
process. */
-int sched_multi = 0;
+bool sched_multi = false;
/* Try to setup for software single stepping over the specified location.
Return 1 if target_resume() should use hardware single step.
valid. */
if (step_over_info_valid_p ()
|| displaced_step_in_progress (tp->inf))
- target_pass_signals (0, NULL);
+ target_pass_signals ({});
else
- target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+ target_pass_signals (signal_pass);
target_resume (resume_ptid, step, sig);
fprintf_unfiltered (gdb_stdlog,
"infrun: resume: thread %s has pending wait "
"status %s (currently_stepping=%d).\n",
- target_pid_to_str (tp->ptid), statstr.c_str (),
+ target_pid_to_str (tp->ptid).c_str (),
+ statstr.c_str (),
currently_stepping (tp));
}
if (sig != GDB_SIGNAL_0)
{
warning (_("Couldn't deliver signal %s to %s."),
- gdb_signal_to_name (sig), target_pid_to_str (tp->ptid));
+ gdb_signal_to_name (sig),
+ target_pid_to_str (tp->ptid).c_str ());
}
tp->suspend.stop_signal = GDB_SIGNAL_0;
"trap_expected=%d, current thread [%s] at %s\n",
step, gdb_signal_to_symbol_string (sig),
tp->control.trap_expected,
- target_pid_to_str (inferior_ptid),
+ target_pid_to_str (inferior_ptid).c_str (),
paddress (gdbarch, pc));
/* Normally, by the time we reach `resume', the breakpoints are either
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: resume: [%s] stepped breakpoint\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
tp->stepped_breakpoint = 1;
static void
resume (gdb_signal sig)
{
- TRY
+ try
{
resume_1 (sig);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
/* If resuming is being aborted for any reason, delete any
single-step breakpoint resume_1 may have created, to avoid
we're running in non-stop mode. */
if (inferior_ptid != null_ptid)
delete_single_step_breakpoints (inferior_thread ());
- throw_exception (ex);
+ throw;
}
- END_CATCH
}
\f
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: clear_proceed_status_thread (%s)\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
/* If we're starting a new sequence, then the previous finished
single-step is no longer relevant. */
"infrun: clear_proceed_status: pending "
"event of %s was a finished step. "
"Discarding.\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
tp->suspend.waitstatus_pending_p = 0;
tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
"infrun: clear_proceed_status_thread: thread %s "
"has pending wait status %s "
"(currently_stepping=%d).\n",
- target_pid_to_str (tp->ptid), statstr.c_str (),
+ target_pid_to_str (tp->ptid).c_str (),
+ statstr.c_str (),
currently_stepping (tp));
}
}
if (!signal_pass_state (tp->suspend.stop_signal))
tp->suspend.stop_signal = GDB_SIGNAL_0;
- thread_fsm_delete (tp->thread_fsm);
+ delete tp->thread_fsm;
tp->thread_fsm = NULL;
tp->control.trap_expected = 0;
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: need to step-over [%s] first\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
thread_step_over_chain_enqueue (tp);
}
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: proceed: [%s] resumed\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
continue;
}
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: proceed: [%s] needs step-over\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
continue;
}
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: proceed: resuming %s\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
reset_ecs (ecs, tp);
switch_to_thread (tp);
waiton_ptid.lwp (),
waiton_ptid.tid ());
if (waiton_ptid.pid () != -1)
- stb.printf (" [%s]", target_pid_to_str (waiton_ptid));
+ stb.printf (" [%s]", target_pid_to_str (waiton_ptid).c_str ());
stb.printf (", status) =\n");
stb.printf ("infrun: %d.%ld.%ld [%s],\n",
result_ptid.pid (),
result_ptid.lwp (),
result_ptid.tid (),
- target_pid_to_str (result_ptid));
+ target_pid_to_str (result_ptid).c_str ());
stb.printf ("infrun: %s\n", status_string.c_str ());
/* This uses %s in part to handle %'s in the text, but also to avoid
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: Waiting for specific thread %s.\n",
- target_pid_to_str (ptid));
+ target_pid_to_str (ptid).c_str ());
/* We have a specific thread to check. */
tp = find_thread_ptid (ptid);
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: PC of %s changed. was=%s, now=%s\n",
- target_pid_to_str (tp->ptid),
+ target_pid_to_str (tp->ptid).c_str (),
paddress (gdbarch, tp->suspend.stop_pc),
paddress (gdbarch, pc));
discard = 1;
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: previous breakpoint of %s, at %s gone\n",
- target_pid_to_str (tp->ptid),
+ target_pid_to_str (tp->ptid).c_str (),
paddress (gdbarch, pc));
discard = 1;
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: pending event of %s cancelled.\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
tp->suspend.waitstatus.kind = TARGET_WAITKIND_SPURIOUS;
tp->suspend.stop_reason = TARGET_STOPPED_BY_NO_REASON;
fprintf_unfiltered (gdb_stdlog,
"infrun: Using pending wait status %s for %s.\n",
statstr.c_str (),
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
}
/* Now that we've selected our final event LWP, un-adjust its PC
input. */
static void
-reinstall_readline_callback_handler_cleanup (void *arg)
+reinstall_readline_callback_handler_cleanup ()
{
struct ui *ui = current_ui;
{
if (ecs->event_thread != NULL
&& ecs->event_thread->thread_fsm != NULL)
- thread_fsm_clean_up (ecs->event_thread->thread_fsm,
- ecs->event_thread);
+ ecs->event_thread->thread_fsm->clean_up (ecs->event_thread);
if (!non_stop)
{
continue;
switch_to_thread (thr);
- thread_fsm_clean_up (thr->thread_fsm, thr);
+ thr->thread_fsm->clean_up (thr);
}
if (ecs->event_thread != NULL)
{
struct execution_control_state ecss;
struct execution_control_state *ecs = &ecss;
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
int cmd_done = 0;
ptid_t waiton_ptid = minus_one_ptid;
scoped_restore save_ui = make_scoped_restore (¤t_ui, main_ui);
/* End up with readline processing input, if necessary. */
- make_cleanup (reinstall_readline_callback_handler_cleanup, NULL);
-
- /* We're handling a live event, so make sure we're doing live
- debugging. If we're looking at traceframes while the target is
- running, we're going to need to get back to that mode after
- handling the event. */
- gdb::optional<scoped_restore_current_traceframe> maybe_restore_traceframe;
- if (non_stop)
- {
- maybe_restore_traceframe.emplace ();
- set_current_traceframe (-1);
- }
-
- gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
-
- if (non_stop)
- /* In non-stop mode, the user/frontend should not notice a thread
- switch due to internal events. Make sure we reverse to the
- user selected thread and frame after handling the event and
- running any breakpoint commands. */
- maybe_restore_thread.emplace ();
-
- overlay_cache_invalid = 1;
- /* Flush target cache before starting to handle each event. Target
- was running and cache could be stale. This is just a heuristic.
- Running threads may modify target memory, but we don't get any
- event. */
- target_dcache_invalidate ();
-
- scoped_restore save_exec_dir
- = make_scoped_restore (&execution_direction, target_execution_direction ());
-
- ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
- target_can_async_p () ? TARGET_WNOHANG : 0);
-
- if (debug_infrun)
- print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
-
- /* If an error happens while handling the event, propagate GDB's
- knowledge of the executing state to the frontend/user running
- state. */
- ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
- scoped_finish_thread_state finish_state (finish_ptid);
-
- /* Get executed before make_cleanup_restore_current_thread above to apply
- still for the thread which has thrown the exception. */
- auto defer_bpstat_clear
- = make_scope_exit (bpstat_clear_actions);
- auto defer_delete_threads
- = make_scope_exit (delete_just_stopped_threads_infrun_breakpoints);
-
- /* Now figure out what to do with the result of the result. */
- handle_inferior_event (ecs);
+ {
+ SCOPE_EXIT { reinstall_readline_callback_handler_cleanup (); };
+
+ /* We're handling a live event, so make sure we're doing live
+ debugging. If we're looking at traceframes while the target is
+ running, we're going to need to get back to that mode after
+ handling the event. */
+ gdb::optional<scoped_restore_current_traceframe> maybe_restore_traceframe;
+ if (non_stop)
+ {
+ maybe_restore_traceframe.emplace ();
+ set_current_traceframe (-1);
+ }
- if (!ecs->wait_some_more)
- {
- struct inferior *inf = find_inferior_ptid (ecs->ptid);
- int should_stop = 1;
- struct thread_info *thr = ecs->event_thread;
+ gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
+
+ if (non_stop)
+ /* In non-stop mode, the user/frontend should not notice a thread
+ switch due to internal events. Make sure we reverse to the
+ user selected thread and frame after handling the event and
+ running any breakpoint commands. */
+ maybe_restore_thread.emplace ();
+
+ overlay_cache_invalid = 1;
+ /* Flush target cache before starting to handle each event. Target
+ was running and cache could be stale. This is just a heuristic.
+ Running threads may modify target memory, but we don't get any
+ event. */
+ target_dcache_invalidate ();
+
+ scoped_restore save_exec_dir
+ = make_scoped_restore (&execution_direction,
+ target_execution_direction ());
+
+ ecs->ptid = do_target_wait (waiton_ptid, &ecs->ws,
+ target_can_async_p () ? TARGET_WNOHANG : 0);
+
+ if (debug_infrun)
+ print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
+
+ /* If an error happens while handling the event, propagate GDB's
+ knowledge of the executing state to the frontend/user running
+ state. */
+ ptid_t finish_ptid = !target_is_non_stop_p () ? minus_one_ptid : ecs->ptid;
+ scoped_finish_thread_state finish_state (finish_ptid);
+
+ /* Get executed before scoped_restore_current_thread above to apply
+ still for the thread which has thrown the exception. */
+ auto defer_bpstat_clear
+ = make_scope_exit (bpstat_clear_actions);
+ auto defer_delete_threads
+ = make_scope_exit (delete_just_stopped_threads_infrun_breakpoints);
+
+ /* Now figure out what to do with the result of the result. */
+ handle_inferior_event (ecs);
+
+ if (!ecs->wait_some_more)
+ {
+ struct inferior *inf = find_inferior_ptid (ecs->ptid);
+ int should_stop = 1;
+ struct thread_info *thr = ecs->event_thread;
- delete_just_stopped_threads_infrun_breakpoints ();
+ delete_just_stopped_threads_infrun_breakpoints ();
- if (thr != NULL)
- {
- struct thread_fsm *thread_fsm = thr->thread_fsm;
+ if (thr != NULL)
+ {
+ struct thread_fsm *thread_fsm = thr->thread_fsm;
- if (thread_fsm != NULL)
- should_stop = thread_fsm_should_stop (thread_fsm, thr);
- }
+ if (thread_fsm != NULL)
+ should_stop = thread_fsm->should_stop (thr);
+ }
- if (!should_stop)
- {
- keep_going (ecs);
- }
- else
- {
- int should_notify_stop = 1;
- int proceeded = 0;
+ if (!should_stop)
+ {
+ keep_going (ecs);
+ }
+ else
+ {
+ bool should_notify_stop = true;
+ int proceeded = 0;
- clean_up_just_stopped_threads_fsms (ecs);
+ clean_up_just_stopped_threads_fsms (ecs);
- if (thr != NULL && thr->thread_fsm != NULL)
- {
- should_notify_stop
- = thread_fsm_should_notify_stop (thr->thread_fsm);
- }
+ if (thr != NULL && thr->thread_fsm != NULL)
+ should_notify_stop = thr->thread_fsm->should_notify_stop ();
- if (should_notify_stop)
- {
- /* We may not find an inferior if this was a process exit. */
- if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
- proceeded = normal_stop ();
- }
+ if (should_notify_stop)
+ {
+ /* We may not find an inferior if this was a process exit. */
+ if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
+ proceeded = normal_stop ();
+ }
- if (!proceeded)
- {
- inferior_event_handler (INF_EXEC_COMPLETE, NULL);
- cmd_done = 1;
- }
- }
- }
+ if (!proceeded)
+ {
+ inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+ cmd_done = 1;
+ }
+ }
+ }
- defer_delete_threads.release ();
- defer_bpstat_clear.release ();
+ defer_delete_threads.release ();
+ defer_bpstat_clear.release ();
- /* No error, don't finish the thread states yet. */
- finish_state.release ();
+ /* No error, don't finish the thread states yet. */
+ finish_state.release ();
- /* Revert thread and frame. */
- do_cleanups (old_chain);
+ /* This scope is used to ensure that readline callbacks are
+ reinstalled here. */
+ }
/* If a UI was in sync execution mode, and now isn't, restore its
prompt (a synchronous execution command has finished, and we're
&& ecs->event_thread != inferior_thread ())
{
fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
- target_pid_to_str (inferior_ptid));
+ target_pid_to_str (inferior_ptid).c_str ());
fprintf_unfiltered (gdb_stdlog, "to %s\n",
- target_pid_to_str (ecs->ptid));
+ target_pid_to_str (ecs->ptid).c_str ());
}
switch_to_thread (ecs->event_thread);
return 0;
}
+/* Look for an inline frame that is marked for skip.
+ If PREV_FRAME is TRUE start at the previous frame,
+ otherwise start at the current frame. Stop at the
+ first non-inline frame, or at the frame where the
+ step started. */
+
+static bool
+inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
+{
+ struct frame_info *frame = get_current_frame ();
+
+ if (prev_frame)
+ frame = get_prev_frame (frame);
+
+ for (; frame != NULL; frame = get_prev_frame (frame))
+ {
+ const char *fn = NULL;
+ symtab_and_line sal;
+ struct symbol *sym;
+
+ if (frame_id_eq (get_frame_id (frame), tp->control.step_frame_id))
+ break;
+ if (get_frame_type (frame) != INLINE_FRAME)
+ break;
+
+ sal = find_frame_sal (frame);
+ sym = get_frame_function (frame);
+
+ if (sym != NULL)
+ fn = sym->print_name ();
+
+ if (sal.line != 0
+ && function_name_is_marked_for_skip (fn, sal))
+ return true;
+ }
+
+ return false;
+}
+
/* If the event thread has the stop requested flag set, pretend it
stopped for a GDB_SIGNAL_0 (i.e., as if it stopped due to
target_stop). */
{
if (!ecs->stop_func_filled_in)
{
+ const block *block;
+
/* Don't care about return value; stop_func_start and stop_func_name
will both be 0 if it doesn't work. */
- find_function_entry_range_from_pc (ecs->event_thread->suspend.stop_pc,
- &ecs->stop_func_name,
- &ecs->stop_func_start,
- &ecs->stop_func_end);
- ecs->stop_func_start
- += gdbarch_deprecated_function_start_offset (gdbarch);
-
- if (gdbarch_skip_entrypoint_p (gdbarch))
- ecs->stop_func_start = gdbarch_skip_entrypoint (gdbarch,
- ecs->stop_func_start);
+ find_pc_partial_function (ecs->event_thread->suspend.stop_pc,
+ &ecs->stop_func_name,
+ &ecs->stop_func_start,
+ &ecs->stop_func_end,
+ &block);
+
+ /* The call to find_pc_partial_function, above, will set
+ stop_func_start and stop_func_end to the start and end
+ of the range containing the stop pc. If this range
+ contains the entry pc for the block (which is always the
+ case for contiguous blocks), advance stop_func_start past
+ the function's start offset and entrypoint. Note that
+ stop_func_start is NOT advanced when in a range of a
+ non-contiguous block that does not contain the entry pc. */
+ if (block != nullptr
+ && ecs->stop_func_start <= BLOCK_ENTRY_PC (block)
+ && BLOCK_ENTRY_PC (block) < ecs->stop_func_end)
+ {
+ ecs->stop_func_start
+ += gdbarch_deprecated_function_start_offset (gdbarch);
+
+ if (gdbarch_skip_entrypoint_p (gdbarch))
+ ecs->stop_func_start
+ = gdbarch_skip_entrypoint (gdbarch, ecs->stop_func_start);
+ }
ecs->stop_func_filled_in = 1;
}
fprintf_unfiltered (gdb_stdlog,
"infrun: %s executing, "
"need stop\n",
- target_pid_to_str (t->ptid));
+ target_pid_to_str (t->ptid).c_str ());
target_stop (t->ptid);
t->stop_requested = 1;
}
fprintf_unfiltered (gdb_stdlog,
"infrun: %s executing, "
"already stopping\n",
- target_pid_to_str (t->ptid));
+ target_pid_to_str (t->ptid).c_str ());
}
if (t->stop_requested)
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: %s not executing\n",
- target_pid_to_str (t->ptid));
+ target_pid_to_str (t->ptid).c_str ());
/* The thread may be not executing, but still be
resumed with a pending status to process. */
pass = -1;
event_ptid = wait_one (&ws);
-
- if (ws.kind == TARGET_WAITKIND_NO_RESUMED)
+ if (debug_infrun)
{
- /* All resumed threads exited. */
+ fprintf_unfiltered (gdb_stdlog,
+ "infrun: stop_all_threads %s %s\n",
+ target_waitstatus_to_string (&ws).c_str (),
+ target_pid_to_str (event_ptid).c_str ());
}
- else if (ws.kind == TARGET_WAITKIND_THREAD_EXITED
- || ws.kind == TARGET_WAITKIND_EXITED
- || ws.kind == TARGET_WAITKIND_SIGNALLED)
- {
- if (debug_infrun)
- {
- ptid_t ptid = ptid_t (ws.value.integer);
- fprintf_unfiltered (gdb_stdlog,
- "infrun: %s exited while "
- "stopping threads\n",
- target_pid_to_str (ptid));
- }
+ if (ws.kind == TARGET_WAITKIND_NO_RESUMED
+ || ws.kind == TARGET_WAITKIND_THREAD_EXITED
+ || ws.kind == TARGET_WAITKIND_EXITED
+ || ws.kind == TARGET_WAITKIND_SIGNALLED)
+ {
+ /* All resumed threads exited
+ or one thread/process exited/signalled. */
}
else
{
"infrun: displaced-step of %s "
"canceled: adding back to the "
"step-over queue\n",
- target_pid_to_str (t->ptid));
+ target_pid_to_str (t->ptid).c_str ());
}
t->control.trap_expected = 0;
thread_step_over_chain_enqueue (t);
"(currently_stepping=%d)\n",
paddress (target_gdbarch (),
t->suspend.stop_pc),
- target_pid_to_str (t->ptid),
+ target_pid_to_str (t->ptid).c_str (),
currently_stepping (t));
}
}
once). */
static void
-handle_inferior_event_1 (struct execution_control_state *ecs)
+handle_inferior_event (struct execution_control_state *ecs)
{
+ /* Make sure that all temporary struct value objects that were
+ created during the handling of the event get deleted at the
+ end. */
+ scoped_value_mark free_values;
+
enum stop_kind stop_soon;
+ if (debug_infrun)
+ fprintf_unfiltered (gdb_stdlog, "infrun: handle_inferior_event %s\n",
+ target_waitstatus_to_string (&ecs->ws).c_str ());
+
if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
{
/* We had an event in the inferior, but we are not interested in
not stopped, and we are ignoring the event. Another possible
circumstance is any event which the lower level knows will be
reported multiple times without an intervening resume. */
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_IGNORE\n");
prepare_to_wait (ecs);
return;
}
if (ecs->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
{
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_EXITED\n");
prepare_to_wait (ecs);
return;
}
{
/* No unwaited-for children left. IOW, all resumed children
have exited. */
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
-
stop_print_frame = 0;
stop_waiting (ecs);
return;
switch (ecs->ws.kind)
{
case TARGET_WAITKIND_LOADED:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_LOADED\n");
context_switch (ecs);
/* Ignore gracefully during startup of the inferior, as it might
be the shell which has just loaded some objects, otherwise
_("unhandled stop_soon: %d"), (int) stop_soon);
case TARGET_WAITKIND_SPURIOUS:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
if (handle_stop_requested (ecs))
return;
context_switch (ecs);
return;
case TARGET_WAITKIND_THREAD_CREATED:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_THREAD_CREATED\n");
if (handle_stop_requested (ecs))
return;
context_switch (ecs);
case TARGET_WAITKIND_EXITED:
case TARGET_WAITKIND_SIGNALLED:
- if (debug_infrun)
- {
- if (ecs->ws.kind == TARGET_WAITKIND_EXITED)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: TARGET_WAITKIND_EXITED\n");
- else
- fprintf_unfiltered (gdb_stdlog,
- "infrun: TARGET_WAITKIND_SIGNALLED\n");
- }
-
inferior_ptid = ecs->ptid;
set_current_inferior (find_inferior_ptid (ecs->ptid));
set_current_program_space (current_inferior ()->pspace);
the above cases end in a continue or goto. */
case TARGET_WAITKIND_FORKED:
case TARGET_WAITKIND_VFORKED:
- if (debug_infrun)
- {
- if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
- else
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_VFORKED\n");
- }
-
/* Check whether the inferior is displaced stepping. */
{
struct regcache *regcache = get_thread_regcache (ecs->event_thread);
/* Done with the shared memory region. Re-insert breakpoints in
the parent, and keep going. */
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: TARGET_WAITKIND_VFORK_DONE\n");
-
context_switch (ecs);
current_inferior ()->waiting_for_vfork_done = 0;
return;
case TARGET_WAITKIND_EXECD:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_EXECD\n");
/* Note we can't read registers yet (the stop_pc), because we
don't yet know the inferior's post-exec architecture.
/* Be careful not to try to gather much state about a thread
that's in a syscall. It's frequently a losing proposition. */
case TARGET_WAITKIND_SYSCALL_ENTRY:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: TARGET_WAITKIND_SYSCALL_ENTRY\n");
/* Getting the current syscall number. */
if (handle_syscall_event (ecs) == 0)
process_event_stop_test (ecs);
syscall. Stepping one instruction seems to get it back
into user code.) */
case TARGET_WAITKIND_SYSCALL_RETURN:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog,
- "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
if (handle_syscall_event (ecs) == 0)
process_event_stop_test (ecs);
return;
case TARGET_WAITKIND_STOPPED:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
handle_signal_stop (ecs);
return;
case TARGET_WAITKIND_NO_HISTORY:
- if (debug_infrun)
- fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
/* Reverse execution: target ran out of history info. */
/* Switch to the stopped thread. */
}
}
-/* A wrapper around handle_inferior_event_1, which also makes sure
- that all temporary struct value objects that were created during
- the handling of the event get deleted at the end. */
-
-static void
-handle_inferior_event (struct execution_control_state *ecs)
-{
- struct value *mark = value_mark ();
-
- handle_inferior_event_1 (ecs);
- /* Purge all temporary values created during the event handling,
- as it could be a long time before we return to the command level
- where such values would otherwise be purged. */
- value_free_to_mark (mark);
-}
-
/* Restart threads back to what they were trying to do back when we
paused them for an in-line step-over. The EVENT_THREAD thread is
ignored. */
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: "
"[%s] is event thread\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
continue;
}
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: "
"[%s] not meant to be running\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
continue;
}
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: [%s] resumed\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
gdb_assert (tp->executing || tp->suspend.waitstatus_pending_p);
continue;
}
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: "
"[%s] needs step-over\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
gdb_assert (!tp->resumed);
continue;
}
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: "
"[%s] has pending status\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
tp->resumed = 1;
continue;
}
internal_error (__FILE__, __LINE__,
"thread [%s] needs a step-over, but not in "
"step-over queue\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
}
if (currently_stepping (tp))
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: [%s] was stepping\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
keep_going_stepped_thread (tp);
}
else
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: restart threads: [%s] continuing\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
reset_ecs (ecs, tp);
switch_to_thread (tp);
keep_going_pass_signal (ecs);
context_switch (ecs);
insert_breakpoints ();
- restart_threads (ecs->event_thread);
+ {
+ scoped_restore save_defer_tc
+ = make_scoped_defer_target_commit_resume ();
+ restart_threads (ecs->event_thread);
+ }
+ target_commit_resume ();
/* If we have events pending, go through handle_inferior_event
again, picking up a pending event at random. This avoids
"(currently_stepping=%d)\n",
paddress (target_gdbarch (),
tp->suspend.stop_pc),
- target_pid_to_str (tp->ptid),
+ target_pid_to_str (tp->ptid).c_str (),
currently_stepping (tp));
}
fprintf_unfiltered (gdb_stdlog,
"infrun: [%s] hit another thread's "
"single-step breakpoint\n",
- target_pid_to_str (ecs->ptid));
+ target_pid_to_str (ecs->ptid).c_str ());
}
ecs->hit_singlestep_breakpoint = 1;
}
fprintf_unfiltered (gdb_stdlog,
"infrun: [%s] hit its "
"single-step breakpoint\n",
- target_pid_to_str (ecs->ptid));
+ target_pid_to_str (ecs->ptid).c_str ());
}
}
}
return;
}
- /* Note: step_resume_breakpoint may be non-NULL. This occures
+ /* Note: step_resume_breakpoint may be non-NULL. This occurs
when either there's a nested signal, or when there's a
pending signal enabled just as the signal handler returns
(leaving the inferior at the step-resume-breakpoint without
tmp_sal = find_pc_line (ecs->stop_func_start, 0);
if (tmp_sal.line != 0
&& !function_name_is_marked_for_skip (ecs->stop_func_name,
- tmp_sal))
+ tmp_sal)
+ && !inline_frame_is_marked_for_skip (true, ecs->event_thread))
{
if (execution_direction == EXEC_REVERSE)
handle_step_into_function_backward (gdbarch, ecs);
if (call_sal.line == ecs->event_thread->current_line
&& call_sal.symtab == ecs->event_thread->current_symtab)
- step_into_inline_frame (ecs->event_thread);
+ {
+ step_into_inline_frame (ecs->event_thread);
+ if (inline_frame_is_marked_for_skip (false, ecs->event_thread))
+ {
+ keep_going (ecs);
+ return;
+ }
+ }
end_stepping_range (ecs);
return;
fprintf_unfiltered (gdb_stdlog,
"infrun: stepping through inlined function\n");
- if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+ if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL
+ || inline_frame_is_marked_for_skip (false, ecs->event_thread))
keep_going (ecs);
else
end_stepping_range (ecs);
{
fprintf_unfiltered (gdb_stdlog,
"infrun: need to finish step-over of [%s]\n",
- target_pid_to_str (ecs->event_thread->ptid));
+ target_pid_to_str (ecs->event_thread->ptid).c_str ());
}
keep_going (ecs);
return 1;
fprintf_unfiltered (gdb_stdlog,
"infrun: need to step [%s] over single-step "
"breakpoint\n",
- target_pid_to_str (ecs->ptid));
+ target_pid_to_str (ecs->ptid).c_str ());
}
keep_going (ecs);
return 1;
{
fprintf_unfiltered (gdb_stdlog,
"infrun: thread [%s] still needs step-over\n",
- target_pid_to_str (ecs->event_thread->ptid));
+ target_pid_to_str (ecs->event_thread->ptid).c_str ());
}
keep_going (ecs);
return 1;
internal_error (__FILE__, __LINE__,
"[%s] has inconsistent state: "
"trap_expected=%d\n",
- target_pid_to_str (tp->ptid),
+ target_pid_to_str (tp->ptid).c_str (),
tp->control.trap_expected);
}
struct frame_info *frame,
struct symbol *sym)
{
- TRY
+ try
{
struct block_symbol vsym;
struct value *value;
CORE_ADDR handler;
struct breakpoint *bp;
- vsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+ vsym = lookup_symbol_search_name (sym->search_name (),
b, VAR_DOMAIN);
value = read_var_value (vsym.symbol, vsym.block, frame);
/* If the value was optimized out, revert to the old behavior. */
inferior_thread ()->control.exception_resume_breakpoint = bp;
}
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
/* We want to ignore errors here. */
}
- END_CATCH
}
/* A helper for check_exception_resume that sets an
if (!func)
return;
- TRY
+ try
{
const struct block *b;
struct block_iterator iter;
}
}
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
}
- END_CATCH
}
static void
fprintf_unfiltered (gdb_stdlog,
"infrun: %s has trap_expected set, "
"resuming to collect trap\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
/* We haven't yet gotten our trap, and either: intercepted a
non-signal event (e.g., a fork); or took a signal which we
fprintf_unfiltered (gdb_stdlog,
"infrun: step-over already in progress: "
"step-over for %s deferred\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
thread_step_over_chain_enqueue (tp);
}
else
fprintf_unfiltered (gdb_stdlog,
"infrun: step-over in progress: "
"resume of %s deferred\n",
- target_pid_to_str (tp->ptid));
+ target_pid_to_str (tp->ptid).c_str ());
}
}
else
stop_all_threads ();
/* Stop stepping if inserting breakpoints fails. */
- TRY
+ try
{
insert_breakpoints ();
}
- CATCH (e, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &e)
{
exception_print (gdb_stderr, e);
stop_waiting (ecs);
clear_step_over_info ();
return;
}
- END_CATCH
ecs->event_thread->control.trap_expected = (remove_bp || remove_wps);
print_exited_reason (struct ui_out *uiout, int exitstatus)
{
struct inferior *inf = current_inferior ();
- const char *pidstr = target_pid_to_str (ptid_t (inf->pid));
+ std::string pidstr = target_pid_to_str (ptid_t (inf->pid));
annotate_exited (exitstatus);
if (exitstatus)
{
if (uiout->is_mi_like_p ())
uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED));
- uiout->text ("[Inferior ");
- uiout->text (plongest (inf->num));
- uiout->text (" (");
- uiout->text (pidstr);
- uiout->text (") exited with code ");
- uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus);
- uiout->text ("]\n");
+ std::string exit_code_str
+ = string_printf ("0%o", (unsigned int) exitstatus);
+ uiout->message ("[Inferior %s (%s) exited with code %pF]\n",
+ plongest (inf->num), pidstr.c_str (),
+ string_field ("exit-code", exit_code_str.c_str ()));
}
else
{
if (uiout->is_mi_like_p ())
uiout->field_string
("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
- uiout->text ("[Inferior ");
- uiout->text (plongest (inf->num));
- uiout->text (" (");
- uiout->text (pidstr);
- uiout->text (") exited normally]\n");
+ uiout->message ("[Inferior %s (%s) exited normally]\n",
+ plongest (inf->num), pidstr.c_str ());
}
}
const char *name;
uiout->text ("\nThread ");
- uiout->field_fmt ("thread-id", "%s", print_thread_id (thr));
+ uiout->field_string ("thread-id", print_thread_id (thr));
name = thr->name != NULL ? thr->name : target_thread_name (thr);
if (name != NULL)
{
uiout->text (" \"");
- uiout->field_fmt ("name", "%s", name);
+ uiout->field_string ("name", name);
uiout->text ("\"");
}
}
/* See infrun.h. */
void
-print_stop_event (struct ui_out *uiout)
+print_stop_event (struct ui_out *uiout, bool displays)
{
struct target_waitstatus last;
ptid_t last_ptid;
print_stop_location (&last);
/* Display the auto-display expressions. */
- do_displays ();
+ if (displays)
+ do_displays ();
}
tp = inferior_thread ();
if (tp->thread_fsm != NULL
- && thread_fsm_finished_p (tp->thread_fsm))
+ && tp->thread_fsm->finished_p ())
{
struct return_value_info *rv;
- rv = thread_fsm_return_value (tp->thread_fsm);
+ rv = tp->thread_fsm->return_value ();
if (rv != NULL)
print_return_value (uiout, rv);
}
{
target_terminal::ours_for_output ();
printf_filtered (_("[Switching to %s]\n"),
- target_pid_to_str (inferior_ptid));
+ target_pid_to_str (inferior_ptid).c_str ());
annotate_thread_changed ();
}
previous_inferior_ptid = inferior_ptid;
{
stop_context saved_context;
- TRY
+ try
{
execute_cmd_pre_hook (stop_command);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (const gdb_exception &ex)
{
exception_fprintf (gdb_stderr, ex,
"Error while running hook_stop:\n");
}
- END_CATCH
/* If the stop hook resumes the target, then there's no point in
trying to notify about the previous stop; its context is
if (target_has_execution)
{
if (last.kind != TARGET_WAITKIND_SIGNALLED
- && last.kind != TARGET_WAITKIND_EXITED)
+ && last.kind != TARGET_WAITKIND_EXITED
+ && last.kind != TARGET_WAITKIND_NO_RESUMED)
/* Delete the breakpoint we stopped at, if it wants to be deleted.
Delete any breakpoint that is to be deleted at the next stop. */
breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat);
for (i = 0; i < GDB_SIGNAL_LAST; ++i)
signal_catch[i] = info[i] > 0;
signal_cache_update (-1);
- target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+ target_pass_signals (signal_pass);
}
static void
int sigfirst, siglast;
enum gdb_signal oursig;
int allsigs;
- int nsigs;
- unsigned char *sigs;
if (args == NULL)
{
/* Allocate and zero an array of flags for which signals to handle. */
- nsigs = (int) GDB_SIGNAL_LAST;
- sigs = (unsigned char *) alloca (nsigs);
- memset (sigs, 0, nsigs);
+ const size_t nsigs = GDB_SIGNAL_LAST;
+ unsigned char sigs[nsigs] {};
/* Break the command line up into args. */
sigs[signum] = 1;
}
else
- {
- printf_unfiltered (_("Not confirmed, unchanged.\n"));
- gdb_flush (gdb_stdout);
- }
+ printf_unfiltered (_("Not confirmed, unchanged.\n"));
}
break;
case GDB_SIGNAL_0:
if (sigs[signum])
{
signal_cache_update (-1);
- target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
- target_program_signals ((int) GDB_SIGNAL_LAST, signal_program);
+ target_pass_signals (signal_pass);
+ target_program_signals (signal_program);
if (from_tty)
{
/* The point of the try/catch is that if the stack is clobbered,
walking the stack might encounter a garbage pointer and
error() trying to dereference it. */
- TRY
+ try
{
restore_selected_frame (inf_status->selected_frame_id);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
exception_fprintf (gdb_stderr, ex,
"Unable to restore previously selected frame:\n");
innermost frame. */
select_frame (get_current_frame ());
}
- END_CATCH
}
delete inf_status;
void
_initialize_infrun (void)
{
- int i;
- int numsigs;
struct cmd_list_element *c;
/* Register extra event sources in the event loop. */
&setlist,
&showlist);
- numsigs = (int) GDB_SIGNAL_LAST;
- signal_stop = XNEWVEC (unsigned char, numsigs);
- signal_print = XNEWVEC (unsigned char, numsigs);
- signal_program = XNEWVEC (unsigned char, numsigs);
- signal_catch = XNEWVEC (unsigned char, numsigs);
- signal_pass = XNEWVEC (unsigned char, numsigs);
- for (i = 0; i < numsigs; i++)
+ for (size_t i = 0; i < GDB_SIGNAL_LAST; i++)
{
signal_stop[i] = 1;
signal_print[i] = 1;