-/* Copyright (C) 1986-2019 Free Software Foundation, Inc.
+/* Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
struct frame_info;
struct address_space;
struct return_value_info;
+struct process_stratum_target;
+struct thread_info;
/* True if we are debugging run control. */
-extern unsigned int debug_infrun;
+extern bool debug_infrun;
-/* True if we are debugging displaced stepping. */
-extern bool debug_displaced;
+/* Print an "infrun" debug statement. */
+
+#define infrun_debug_printf(fmt, ...) \
+ debug_prefixed_printf_cond (debug_infrun, "infrun",fmt, ##__VA_ARGS__)
+
+/* Print "infrun" start/end debug statements. */
+
+#define INFRUN_SCOPED_DEBUG_START_END(msg) \
+ scoped_debug_start_end (debug_infrun, "infrun", msg)
+
+/* Print "infrun" enter/exit debug statements. */
+
+#define INFRUN_SCOPED_DEBUG_ENTER_EXIT \
+ scoped_debug_enter_exit (debug_infrun, "infrun")
/* Nonzero if we want to give control to the user when we're notified
of shared library events by the dynamic linker. */
resumed. */
extern ptid_t user_visible_resume_ptid (int step);
-extern void wait_for_inferior (void);
+/* Return the process_stratum target that we will proceed, in the
+ perspective of the user/frontend. If RESUME_PTID is
+ MINUS_ONE_PTID, then we'll resume all threads of all targets, so
+ the function returns NULL. Otherwise, we'll be resuming a process
+ or thread of the current process, so we return the current
+ inferior's process stratum target. */
+extern process_stratum_target *user_visible_resume_target (ptid_t resume_ptid);
/* Return control to GDB when the inferior stops for real. Print
appropriate messages, remove breakpoints, give terminal our modes,
target, false otherwise. */
extern int normal_stop (void);
-extern void get_last_target_status (ptid_t *ptid,
+/* Return the cached copy of the last target/ptid/waitstatus returned
+ by target_wait()/deprecated_target_wait_hook(). The data is
+ actually cached by handle_inferior_event(), which gets called
+ immediately after target_wait()/deprecated_target_wait_hook(). */
+extern void get_last_target_status (process_stratum_target **target,
+ ptid_t *ptid,
struct target_waitstatus *status);
-extern void set_last_target_status (ptid_t ptid,
+/* Set the cached copy of the last target/ptid/waitstatus. */
+extern void set_last_target_status (process_stratum_target *target, ptid_t ptid,
struct target_waitstatus status);
+/* Clear the cached copy of the last ptid/waitstatus returned by
+ target_wait(). */
+extern void nullify_last_target_wait_ptid ();
+
/* Stop all threads. Only returns after everything is halted. */
extern void stop_all_threads (void);
extern void prepare_for_detach (void);
-extern void fetch_inferior_event (void *);
+extern void fetch_inferior_event ();
extern void init_wait_for_inferior (void);
triggers a non-steppable watchpoint. */
extern int stepping_past_nonsteppable_watchpoint (void);
-extern void set_step_info (struct frame_info *frame,
+/* Record in TP the frame and location we're currently stepping through. */
+extern void set_step_info (thread_info *tp,
+ struct frame_info *frame,
struct symtab_and_line sal);
/* Several print_*_reason helper functions to print why the inferior
$_exitsignal. */
extern void clear_exit_convenience_vars (void);
-/* Dump LEN bytes at BUF in hex to FILE, followed by a newline. */
-extern void displaced_step_dump_bytes (struct ui_file *file,
- const gdb_byte *buf, size_t len);
-
-extern struct displaced_step_closure *get_displaced_step_closure_by_addr
- (CORE_ADDR addr);
+/* Dump LEN bytes at BUF in hex to a string and return it. */
+extern std::string displaced_step_dump_bytes (const gdb_byte *buf, size_t len);
extern void update_observer_mode (void);
loop. */
extern void mark_infrun_async_event_handler (void);
-/* The global queue of threads that need to do a step-over operation
+/* The global chain of threads that need to do a step-over operation
to get past e.g., a breakpoint. */
-extern struct thread_info *step_over_queue_head;
+extern struct thread_info *global_thread_step_over_chain_head;
/* Remove breakpoints if possible (usually that means, if everything
is stopped). On failure, print a message. */
started or re-started). */
extern void all_uis_on_sync_execution_starting (void);
-/* Base class for displaced stepping closures (the arch-specific data). */
+/* In all-stop, restart the target if it had to be stopped to
+ detach. */
+extern void restart_after_all_stop_detach (process_stratum_target *proc_target);
-struct displaced_step_closure
-{
- virtual ~displaced_step_closure () = 0;
-};
+/* RAII object to temporarily disable the requirement for target
+ stacks to commit their resumed threads.
+
+ On construction, set process_stratum_target::commit_resumed_state
+ to false for all process_stratum targets in all target
+ stacks.
+
+ On destruction (or if reset_and_commit() is called), set
+ process_stratum_target::commit_resumed_state to true for all
+ process_stratum targets in all target stacks, except those that:
+
+ - have no resumed threads
+ - have a resumed thread with a pending status
+
+ target_commit_resumed is not called in the destructor, because its
+ implementations could throw, and we don't to swallow that error in
+ a destructor. Instead, the caller should call the
+ reset_and_commit_resumed() method so that an eventual exception can
+ propagate. "reset" in the method name refers to the fact that this
+ method has the same effect as the destructor, in addition to
+ committing resumes.
+
+ The creation of nested scoped_disable_commit_resumed objects is
+ tracked, such that only the outermost instance actually does
+ something, for cases like this:
+
+ void
+ inner_func ()
+ {
+ scoped_disable_commit_resumed disable;
+
+ // do stuff
-/* A simple displaced step closure that contains only a byte buffer. */
+ disable.reset_and_commit ();
+ }
-struct buf_displaced_step_closure : displaced_step_closure
+ void
+ outer_func ()
+ {
+ scoped_disable_commit_resumed disable;
+
+ for (... each thread ...)
+ inner_func ();
+
+ disable.reset_and_commit ();
+ }
+
+ In this case, we don't want the `disable` destructor in
+ `inner_func` to require targets to commit resumed threads, so that
+ the `reset_and_commit()` call in `inner_func` doesn't actually
+ resume threads. */
+
+struct scoped_disable_commit_resumed
{
- buf_displaced_step_closure (int buf_size)
- : buf (buf_size)
- {}
+ explicit scoped_disable_commit_resumed (const char *reason);
+ ~scoped_disable_commit_resumed ();
+
+ DISABLE_COPY_AND_ASSIGN (scoped_disable_commit_resumed);
+
+ /* Undoes the disabling done by the ctor, and calls
+ maybe_call_commit_resumed_all_targets(). */
+ void reset_and_commit ();
+
+private:
+ /* Undoes the disabling done by the ctor. */
+ void reset ();
+
+ /* Whether this object has been reset. */
+ bool m_reset = false;
- gdb::byte_vector buf;
+ const char *m_reason;
+ bool m_prev_enable_commit_resumed;
};
-/* Per-inferior displaced stepping state. */
-struct displaced_step_inferior_state
+/* Call target_commit_resumed method on all target stacks whose
+ process_stratum target layer has COMMIT_RESUME_STATE set. */
+
+extern void maybe_call_commit_resumed_all_targets ();
+
+/* RAII object to temporarily enable the requirement for target stacks
+ to commit their resumed threads. This is the inverse of
+ scoped_disable_commit_resumed. The constructor calls the
+ maybe_call_commit_resumed_all_targets function itself, since it's
+ OK to throw from a constructor. */
+
+struct scoped_enable_commit_resumed
{
- displaced_step_inferior_state ()
- {
- reset ();
- }
+ explicit scoped_enable_commit_resumed (const char *reason);
+ ~scoped_enable_commit_resumed ();
- /* Put this object back in its original state. */
- void reset ()
- {
- failed_before = 0;
- step_thread = nullptr;
- step_gdbarch = nullptr;
- step_closure = nullptr;
- step_original = 0;
- step_copy = 0;
- step_saved_copy.clear ();
- }
-
- /* True if preparing a displaced step ever failed. If so, we won't
- try displaced stepping for this inferior again. */
- int failed_before;
-
- /* If this is not nullptr, this is the thread carrying out a
- displaced single-step in process PID. This thread's state will
- require fixing up once it has completed its step. */
- thread_info *step_thread;
-
- /* The architecture the thread had when we stepped it. */
- gdbarch *step_gdbarch;
-
- /* The closure provided gdbarch_displaced_step_copy_insn, to be used
- for post-step cleanup. */
- displaced_step_closure *step_closure;
-
- /* The address of the original instruction, and the copy we
- made. */
- CORE_ADDR step_original, step_copy;
-
- /* Saved contents of copy area. */
- gdb::byte_vector step_saved_copy;
+ DISABLE_COPY_AND_ASSIGN (scoped_enable_commit_resumed);
+
+private:
+ const char *m_reason;
+ bool m_prev_enable_commit_resumed;
};
+
#endif /* INFRUN_H */