X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Finfrun.c;h=033699bc3f73c7684ada386a981a614fafb2779d;hb=8b8da1a9f31941fa167c9f2bd2a80cdd1dccb452;hp=d97d469e112909ff89ac6249da41508f8cbb8fed;hpb=183be222907a6f419bd71f70ee650989026f0188;p=binutils-gdb.git diff --git a/gdb/infrun.c b/gdb/infrun.c index d97d469e112..033699bc3f7 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1,7 +1,7 @@ /* Target-struct-independent code to start (run) and stop an inferior process. - Copyright (C) 1986-2021 Free Software Foundation, Inc. + Copyright (C) 1986-2022 Free Software Foundation, Inc. This file is part of GDB. @@ -72,6 +72,7 @@ #include "scoped-mock-context.h" #include "test-target.h" #include "gdbsupport/common-debug.h" +#include "gdbsupport/buildargv.h" /* Prototypes for local functions */ @@ -95,6 +96,13 @@ static void resume (gdb_signal sig); static void wait_for_inferior (inferior *inf); +static void restart_threads (struct thread_info *event_thread, + inferior *inf = nullptr); + +static bool start_step_over (void); + +static bool step_over_info_valid_p (void); + /* Asynchronous signal handler registered as event loop source for when we have pending events ready to be passed to the core. */ static struct async_event_handler *infrun_async_inferior_event_token; @@ -137,7 +145,7 @@ static void show_step_stop_if_no_debug (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("Mode of the step operation is %s.\n"), value); + gdb_printf (file, _("Mode of the step operation is %s.\n"), value); } /* proceed and normal_stop use this to notify the user when the @@ -158,7 +166,7 @@ static void show_debug_infrun (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("Inferior debugging is %s.\n"), value); + gdb_printf (file, _("Inferior debugging is %s.\n"), value); } /* Support for disabling address space randomization. */ @@ -170,14 +178,14 @@ show_disable_randomization (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { if (target_supports_disable_randomization ()) - fprintf_filtered (file, - _("Disabling randomization of debuggee's " - "virtual address space is %s.\n"), - value); + gdb_printf (file, + _("Disabling randomization of debuggee's " + "virtual address space is %s.\n"), + value); else - fputs_filtered (_("Disabling randomization of debuggee's " - "virtual address space is unsupported on\n" - "this platform.\n"), file); + gdb_puts (_("Disabling randomization of debuggee's " + "virtual address space is unsupported on\n" + "this platform.\n"), file); } static void @@ -212,9 +220,9 @@ static void show_non_stop (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, - _("Controlling the inferior in non-stop mode is %s.\n"), - value); + gdb_printf (file, + _("Controlling the inferior in non-stop mode is %s.\n"), + value); } /* "Observer mode" is somewhat like a more extreme version of @@ -256,15 +264,15 @@ set_observer_mode (const char *args, int from_tty, } if (from_tty) - printf_filtered (_("Observer mode is now %s.\n"), - (observer_mode ? "on" : "off")); + gdb_printf (_("Observer mode is now %s.\n"), + (observer_mode ? "on" : "off")); } static void show_observer_mode (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("Observer mode is %s.\n"), value); + gdb_printf (file, _("Observer mode is %s.\n"), value); } /* This updates the value of observer mode based on changes in @@ -284,8 +292,8 @@ update_observer_mode (void) /* Let the user know if things change. */ if (newval != observer_mode) - printf_filtered (_("Observer mode is now %s.\n"), - (newval ? "on" : "off")); + gdb_printf (_("Observer mode is now %s.\n"), + (newval ? "on" : "off")); observer_mode = observer_mode_1 = newval; } @@ -357,8 +365,8 @@ static void show_stop_on_solib_events (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("Stopping for shared library events is %s.\n"), - value); + gdb_printf (file, _("Stopping for shared library events is %s.\n"), + value); } /* True after stop if current stack frame should be printed. */ @@ -366,7 +374,7 @@ show_stop_on_solib_events (struct ui_file *file, int from_tty, static bool stop_print_frame; /* This is a cached copy of the target/ptid/waitstatus of the last - event returned by target_wait()/deprecated_target_wait_hook(). + event returned by target_wait(). This information is returned by get_last_target_status(). */ static process_stratum_target *target_last_proc_target; static ptid_t target_last_wait_ptid; @@ -388,10 +396,10 @@ static void show_follow_fork_mode_string (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, - _("Debugger response to a program " - "call of fork or vfork is \"%s\".\n"), - value); + gdb_printf (file, + _("Debugger response to a program " + "call of fork or vfork is \"%s\".\n"), + value); } @@ -421,7 +429,7 @@ follow_fork_inferior (bool follow_child, bool detach_fork) the parent stays blocked. If we're telling the parent to run in the foreground, the user will not be able to ctrl-c to get back the terminal, effectively hanging the debug session. */ - fprintf_filtered (gdb_stderr, _("\ + gdb_printf (gdb_stderr, _("\ 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")); @@ -431,6 +439,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ inferior *parent_inf = current_inferior (); inferior *child_inf = nullptr; + gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr); + if (!follow_child) { /* Detach new forked process? */ @@ -455,10 +465,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \ ptid_t process_ptid = ptid_t (child_ptid.pid ()); target_terminal::ours_for_output (); - fprintf_filtered (gdb_stdlog, - _("[Detaching after %s from child %s]\n"), - has_vforked ? "vfork" : "fork", - target_pid_to_str (process_ptid).c_str ()); + gdb_printf (_("[Detaching after %s from child %s]\n"), + has_vforked ? "vfork" : "fork", + target_pid_to_str (process_ptid).c_str ()); } } else @@ -492,7 +501,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \ } else { - child_inf->aspace = new_address_space (); + child_inf->aspace = new address_space (); child_inf->pspace = new program_space (child_inf->aspace); child_inf->removable = 1; clone_program_space (child_inf->pspace, parent_inf->pspace); @@ -508,7 +517,8 @@ holding the child stopped. Try \"set detach-on-fork\" or \ insert breakpoints, so that we can debug it. A subsequent child exec or exit is enough to know when does the child stops using the parent's address space. */ - parent_inf->waiting_for_vfork_done = detach_fork; + parent_inf->thread_waiting_for_vfork_done + = detach_fork ? inferior_thread () : nullptr; parent_inf->pspace->breakpoints_not_allowed = detach_fork; } } @@ -522,11 +532,10 @@ holding the child stopped. Try \"set detach-on-fork\" or \ std::string child_pid = target_pid_to_str (child_ptid); target_terminal::ours_for_output (); - fprintf_filtered (gdb_stdlog, - _("[Attaching after %s %s to child %s]\n"), - parent_pid.c_str (), - has_vforked ? "vfork" : "fork", - child_pid.c_str ()); + gdb_printf (_("[Attaching after %s %s to child %s]\n"), + parent_pid.c_str (), + has_vforked ? "vfork" : "fork", + child_pid.c_str ()); } /* Add the new inferior first, so that the target_detach below @@ -564,7 +573,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \ child_inf->aspace = parent_inf->aspace; child_inf->pspace = parent_inf->pspace; - parent_inf->aspace = new_address_space (); + parent_inf->aspace = new address_space (); parent_inf->pspace = new program_space (parent_inf->aspace); clone_program_space (parent_inf->pspace, child_inf->pspace); @@ -574,7 +583,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \ } else { - child_inf->aspace = new_address_space (); + child_inf->aspace = new address_space (); child_inf->pspace = new program_space (child_inf->aspace); child_inf->removable = 1; child_inf->symfile_flags = SYMFILE_NO_READ; @@ -603,6 +612,23 @@ holding the child stopped. Try \"set detach-on-fork\" or \ if (child_inf != nullptr) gdb_assert (!child_inf->thread_list.empty ()); + /* Clear the parent thread's pending follow field. Do this before calling + target_detach, so that the target can differentiate the two following + cases: + + - We continue past a fork with "follow-fork-mode == child" && + "detach-on-fork on", and therefore detach the parent. In that + case the target should not detach the fork child. + - We run to a fork catchpoint and the user types "detach". In that + case, the target should detach the fork child in addition to the + parent. + + The former case will have pending_follow cleared, the later will have + pending_follow set. */ + thread_info *parent_thread = find_thread_ptid (parent_inf, parent_ptid); + gdb_assert (parent_thread != nullptr); + parent_thread->pending_follow.set_spurious (); + /* Detach the parent if needed. */ if (follow_child) { @@ -624,7 +650,6 @@ holding the child stopped. Try \"set detach-on-fork\" or \ child_inf->pending_detach = 0; parent_inf->vfork_child = child_inf; parent_inf->pending_detach = detach_fork; - parent_inf->waiting_for_vfork_done = 0; } else if (detach_fork) { @@ -634,10 +659,9 @@ holding the child stopped. Try \"set detach-on-fork\" or \ ptid_t process_ptid = ptid_t (parent_ptid.pid ()); target_terminal::ours_for_output (); - fprintf_filtered (gdb_stdlog, - _("[Detaching after fork from " - "parent %s]\n"), - target_pid_to_str (process_ptid).c_str ()); + gdb_printf (_("[Detaching after fork from " + "parent %s]\n"), + target_pid_to_str (process_ptid).c_str ()); } target_detach (parent_inf, 0); @@ -671,7 +695,6 @@ follow_fork () { bool follow_child = (follow_fork_mode_string == follow_fork_mode_child); bool should_resume = true; - struct thread_info *tp; /* Copy user stepping state to the new inferior thread. FIXME: the followed fork child thread should have a copy of most of the @@ -684,7 +707,6 @@ follow_fork () int current_line = 0; symtab *current_symtab = NULL; struct frame_id step_frame_id = { 0 }; - struct thread_fsm *thread_fsm = NULL; if (!non_stop) { @@ -717,7 +739,7 @@ follow_fork () } } - tp = inferior_thread (); + thread_info *tp = inferior_thread (); /* If there were any forks/vforks that were caught and are now to be followed, then do so now. */ @@ -727,6 +749,7 @@ follow_fork () case TARGET_WAITKIND_VFORKED: { ptid_t parent, child; + std::unique_ptr thread_fsm; /* If the user did a next/step, etc, over a fork call, preserve the stepping state in the fork child. */ @@ -741,7 +764,7 @@ follow_fork () step_frame_id = tp->control.step_frame_id; exception_resume_breakpoint = clone_momentary_breakpoint (tp->control.exception_resume_breakpoint); - thread_fsm = tp->thread_fsm; + thread_fsm = tp->release_thread_fsm (); /* For now, delete the parent's sr breakpoint, otherwise, parent/child sr breakpoints are considered duplicates, @@ -753,12 +776,17 @@ follow_fork () tp->control.step_range_end = 0; tp->control.step_frame_id = null_frame_id; delete_exception_resume_breakpoint (tp); - tp->thread_fsm = NULL; } parent = inferior_ptid; child = tp->pending_follow.child_ptid (); + /* If handling a vfork, stop all the inferior's threads, they will be + restarted when the vfork shared region is complete. */ + if (tp->pending_follow.kind () == TARGET_WAITKIND_VFORKED + && target_is_non_stop_p ()) + stop_all_threads ("handling vfork", tp->inf); + process_stratum_target *parent_targ = tp->inf->process_target (); /* Set up inferior(s) as specified by the caller, and tell the target to do whatever is necessary to follow either parent @@ -771,14 +799,6 @@ follow_fork () } else { - /* This pending follow fork event is now handled, one way - or another. The previous selected thread may be gone - from the lists by now, but if it is still around, need - to clear the pending follow request. */ - tp = find_thread_ptid (parent_targ, parent); - if (tp) - tp->pending_follow.set_spurious (); - /* This makes sure we don't try to apply the "Switched over from WAIT_PID" logic above. */ nullify_last_target_wait_ptid (); @@ -803,7 +823,7 @@ follow_fork () tp->control.step_frame_id = step_frame_id; tp->control.exception_resume_breakpoint = exception_resume_breakpoint; - tp->thread_fsm = thread_fsm; + tp->set_thread_fsm (std::move (thread_fsm)); } else { @@ -888,7 +908,7 @@ proceed_after_vfork_done (thread_info *thread) && thread->stop_signal () == GDB_SIGNAL_0) { infrun_debug_printf ("resuming vfork parent thread %s", - target_pid_to_str (thread->ptid).c_str ()); + thread->ptid.to_string ().c_str ()); switch_to_thread (thread); clear_proceed_status (0); @@ -957,15 +977,13 @@ handle_vfork_child_exec_or_exit (int exec) if (exec) { - fprintf_filtered (gdb_stdlog, - _("[Detaching vfork parent %s " - "after child exec]\n"), pidstr.c_str ()); + gdb_printf (_("[Detaching vfork parent %s " + "after child exec]\n"), pidstr.c_str ()); } else { - fprintf_filtered (gdb_stdlog, - _("[Detaching vfork parent %s " - "after child exit]\n"), pidstr.c_str ()); + gdb_printf (_("[Detaching vfork parent %s " + "after child exit]\n"), pidstr.c_str ()); } } @@ -1030,6 +1048,55 @@ handle_vfork_child_exec_or_exit (int exec) } } +/* Handle TARGET_WAITKIND_VFORK_DONE. */ + +static void +handle_vfork_done (thread_info *event_thread) +{ + /* We only care about this event if inferior::thread_waiting_for_vfork_done is + set, that is if we are waiting for a vfork child not under our control + (because we detached it) to exec or exit. + + If an inferior has vforked and we are debugging the child, we don't use + the vfork-done event to get notified about the end of the shared address + space window. We rely instead on the child's exec or exit event, and the + inferior::vfork_{parent,child} fields are used instead. See + handle_vfork_child_exec_or_exit for that. */ + if (event_thread->inf->thread_waiting_for_vfork_done == nullptr) + { + infrun_debug_printf ("not waiting for a vfork-done event"); + return; + } + + INFRUN_SCOPED_DEBUG_ENTER_EXIT; + + /* We stopped all threads (other than the vforking thread) of the inferior in + follow_fork and kept them stopped until now. It should therefore not be + possible for another thread to have reported a vfork during that window. + If THREAD_WAITING_FOR_VFORK_DONE is set, it has to be the same thread whose + vfork-done we are handling right now. */ + gdb_assert (event_thread->inf->thread_waiting_for_vfork_done == event_thread); + + event_thread->inf->thread_waiting_for_vfork_done = nullptr; + event_thread->inf->pspace->breakpoints_not_allowed = 0; + + /* On non-stop targets, we stopped all the inferior's threads in follow_fork, + resume them now. On all-stop targets, everything that needs to be resumed + will be when we resume the event thread. */ + if (target_is_non_stop_p ()) + { + /* restart_threads and start_step_over may change the current thread, make + sure we leave the event thread as the current thread. */ + scoped_restore_current_thread restore_thread; + + insert_breakpoints (); + start_step_over (); + + if (!step_over_info_valid_p ()) + restart_threads (event_thread, event_thread->inf); + } +} + /* Enum strings for "set|show follow-exec-mode". */ static const char follow_exec_mode_new[] = "new"; @@ -1046,7 +1113,7 @@ static void show_follow_exec_mode_string (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("Follow exec mode is \"%s\".\n"), value); + gdb_printf (file, _("Follow exec mode is \"%s\".\n"), value); } /* EXEC_FILE_TARGET is assumed to be non-NULL. */ @@ -1127,9 +1194,9 @@ follow_exec (ptid_t ptid, const char *exec_file_target) /* 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).c_str (), - exec_file_target); + gdb_printf (_("%s is executing new program: %s\n"), + 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. */ @@ -1481,6 +1548,7 @@ static void infrun_inferior_exit (struct inferior *inf) { inf->displaced_step_state.reset (); + inf->thread_waiting_for_vfork_done = nullptr; } static void @@ -1499,6 +1567,8 @@ infrun_inferior_execd (inferior *inf) one in progress at the time of the exec, it must have been the exec'ing thread. */ clear_step_over_info (); + + inf->thread_waiting_for_vfork_done = nullptr; } /* If ON, and the architecture supports it, GDB will use displaced @@ -1516,14 +1586,14 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty, const char *value) { if (can_use_displaced_stepping == AUTO_BOOLEAN_AUTO) - fprintf_filtered (file, - _("Debugger's willingness to use displaced stepping " - "to step over breakpoints is %s (currently %s).\n"), - value, target_is_non_stop_p () ? "on" : "off"); + gdb_printf (file, + _("Debugger's willingness to use displaced stepping " + "to step over breakpoints is %s (currently %s).\n"), + value, target_is_non_stop_p () ? "on" : "off"); else - fprintf_filtered (file, - _("Debugger's willingness to use displaced stepping " - "to step over breakpoints is %s.\n"), value); + gdb_printf (file, + _("Debugger's willingness to use displaced stepping " + "to step over breakpoints is %s.\n"), value); } /* Return true if the gdbarch implements the required methods to use @@ -1652,14 +1722,14 @@ displaced_step_prepare_throw (thread_info *tp) it is likely that it will return unavailable, so don't bother asking. */ displaced_debug_printf ("deferring step of %s", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); global_thread_step_over_chain_enqueue (tp); return DISPLACED_STEP_PREPARE_STATUS_UNAVAILABLE; } displaced_debug_printf ("displaced-stepping %s now", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); scoped_restore_current_thread restore_thread; @@ -1674,7 +1744,7 @@ displaced_step_prepare_throw (thread_info *tp) if (status == DISPLACED_STEP_PREPARE_STATUS_CANT) { displaced_debug_printf ("failed to prepare (%s)", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); return DISPLACED_STEP_PREPARE_STATUS_CANT; } @@ -1685,7 +1755,7 @@ displaced_step_prepare_throw (thread_info *tp) displaced_debug_printf ("not enough resources available, " "deferring step of %s", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); global_thread_step_over_chain_enqueue (tp); @@ -1702,7 +1772,7 @@ displaced_step_prepare_throw (thread_info *tp) displaced_debug_printf ("prepared successfully thread=%s, " "original_pc=%s, displaced_pc=%s", - target_pid_to_str (tp->ptid).c_str (), + tp->ptid.to_string ().c_str (), paddress (gdbarch, original_pc), paddress (gdbarch, displaced_pc)); @@ -1901,6 +1971,16 @@ start_step_over (void) continue; } + if (tp->inf->thread_waiting_for_vfork_done != nullptr) + { + /* When we stop all threads, handling a vfork, any thread in the step + over chain remains there. A user could also try to continue a + thread stopped at a breakpoint while another thread is waiting for + a vfork-done event. In any case, we don't want to start a step + over right now. */ + continue; + } + /* Remove thread from the THREADS_TO_STEP chain. If anything goes wrong while we try to prepare the displaced step, we don't add it back to the global step over chain. This is to avoid a thread staying in the @@ -1930,14 +2010,14 @@ start_step_over (void) internal_error (__FILE__, __LINE__, "[%s] has inconsistent state: " "trap_expected=%d, resumed=%d, executing=%d\n", - target_pid_to_str (tp->ptid).c_str (), + tp->ptid.to_string ().c_str (), tp->control.trap_expected, tp->resumed (), tp->executing ()); } infrun_debug_printf ("resuming [%s] for step-over", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().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 @@ -1960,13 +2040,13 @@ start_step_over (void) if (tp->resumed ()) { infrun_debug_printf ("[%s] was resumed.", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); gdb_assert (!thread_is_in_step_over_chain (tp)); } else { infrun_debug_printf ("[%s] was NOT resumed.", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); gdb_assert (thread_is_in_step_over_chain (tp)); } @@ -2030,10 +2110,10 @@ static void show_scheduler_mode (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, - _("Mode for locking scheduler " - "during execution is \"%s\".\n"), - value); + gdb_printf (file, + _("Mode for locking scheduler " + "during execution is \"%s\".\n"), + value); } static void @@ -2136,8 +2216,41 @@ internal_resume_ptid (int user_step) return a wildcard ptid. */ if (target_is_non_stop_p ()) return inferior_ptid; - else - return user_visible_resume_ptid (user_step); + + /* The rest of the function assumes non-stop==off and + target-non-stop==off. + + If a thread is waiting for a vfork-done event, it means breakpoints are out + for this inferior (well, program space in fact). We don't want to resume + any thread other than the one waiting for vfork done, otherwise these other + threads could miss breakpoints. So if a thread in the resumption set is + waiting for a vfork-done event, resume only that thread. + + The resumption set width depends on whether schedule-multiple is on or off. + + Note that if the target_resume interface was more flexible, we could be + smarter here when schedule-multiple is on. For example, imagine 3 + inferiors with 2 threads each (1.1, 1.2, 2.1, 2.2, 3.1 and 3.2). Threads + 2.1 and 3.2 are both waiting for a vfork-done event. Then we could ask the + target(s) to resume: + + - All threads of inferior 1 + - Thread 2.1 + - Thread 3.2 + + Since we don't have that flexibility (we can only pass one ptid), just + resume the first thread waiting for a vfork-done event we find (e.g. thread + 2.1). */ + if (sched_multi) + { + for (inferior *inf : all_non_exited_inferiors ()) + if (inf->thread_waiting_for_vfork_done != nullptr) + return inf->thread_waiting_for_vfork_done->ptid; + } + else if (current_inferior ()->thread_waiting_for_vfork_done != nullptr) + return current_inferior ()->thread_waiting_for_vfork_done->ptid; + + return user_visible_resume_ptid (user_step); } /* Wrapper for target_resume, that handles infrun-specific @@ -2182,10 +2295,11 @@ do_target_resume (ptid_t resume_ptid, bool step, enum gdb_signal sig) else target_pass_signals (signal_pass); - target_resume (resume_ptid, step, sig); + infrun_debug_printf ("resume_ptid=%s, step=%d, sig=%s", + resume_ptid.to_string ().c_str (), + step, gdb_signal_to_symbol_string (sig)); - if (target_can_async_p ()) - target_async (1); + target_resume (resume_ptid, step, sig); } /* Resume the inferior. SIG is the signal to give the inferior @@ -2218,8 +2332,8 @@ resume_1 (enum gdb_signal sig) infrun_debug_printf ("thread %s has pending wait " "status %s (currently_stepping=%d).", - target_pid_to_str (tp->ptid).c_str (), - target_waitstatus_to_string (&tp->pending_waitstatus ()).c_str (), + tp->ptid.to_string ().c_str (), + tp->pending_waitstatus ().to_string ().c_str (), currently_stepping (tp)); tp->inf->process_target ()->threads_executing = true; @@ -2232,14 +2346,14 @@ resume_1 (enum gdb_signal sig) { warning (_("Couldn't deliver signal %s to %s."), gdb_signal_to_name (sig), - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); } tp->set_stop_signal (GDB_SIGNAL_0); if (target_can_async_p ()) { - target_async (1); + target_async (true); /* Tell the event loop we have an event to process. */ mark_async_event_handler (infrun_async_inferior_event_token); } @@ -2251,7 +2365,7 @@ resume_1 (enum gdb_signal sig) /* Depends on stepped_breakpoint. */ step = currently_stepping (tp); - if (current_inferior ()->waiting_for_vfork_done) + if (current_inferior ()->thread_waiting_for_vfork_done != nullptr) { /* Don't try to single-step a vfork parent that is waiting for the child to get out of the shared memory region (by exec'ing @@ -2274,7 +2388,7 @@ resume_1 (enum gdb_signal sig) "current thread [%s] at %s", step, gdb_signal_to_symbol_string (sig), tp->control.trap_expected, - target_pid_to_str (inferior_ptid).c_str (), + inferior_ptid.to_string ().c_str (), paddress (gdbarch, pc)); /* Normally, by the time we reach `resume', the breakpoints are either @@ -2371,7 +2485,7 @@ resume_1 (enum gdb_signal sig) && use_displaced_stepping (tp) && !step_over_info_valid_p () && sig == GDB_SIGNAL_0 - && !current_inferior ()->waiting_for_vfork_done) + && current_inferior ()->thread_waiting_for_vfork_done == nullptr) { displaced_step_prepare_status prepare_status = displaced_step_prepare (tp); @@ -2388,7 +2502,7 @@ resume_1 (enum gdb_signal sig) /* Fallback to stepping over the breakpoint in-line. */ if (target_is_non_stop_p ()) - stop_all_threads (); + stop_all_threads ("displaced stepping falling back on inline stepping"); set_step_over_info (regcache->aspace (), regcache_read_pc (regcache), 0, tp->global_num); @@ -2406,8 +2520,8 @@ resume_1 (enum gdb_signal sig) step = gdbarch_displaced_step_hw_singlestep (gdbarch); } else - gdb_assert_not_reached (_("Invalid displaced_step_prepare_status " - "value.")); + gdb_assert_not_reached ("Invalid displaced_step_prepare_status " + "value."); } /* Do we need to do it the hard way, w/temp breakpoints? */ @@ -2515,7 +2629,7 @@ resume_1 (enum gdb_signal sig) do displaced stepping. */ infrun_debug_printf ("resume: [%s] stepped breakpoint", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); tp->stepped_breakpoint = 1; @@ -2617,7 +2731,7 @@ new_stop_id (void) static void clear_proceed_status_thread (struct thread_info *tp) { - infrun_debug_printf ("%s", target_pid_to_str (tp->ptid).c_str ()); + infrun_debug_printf ("%s", tp->ptid.to_string ().c_str ()); /* If we're starting a new sequence, then the previous finished single-step is no longer relevant. */ @@ -2627,7 +2741,7 @@ clear_proceed_status_thread (struct thread_info *tp) { infrun_debug_printf ("pending event of %s was a finished step. " "Discarding.", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); tp->clear_pending_waitstatus (); tp->set_stop_reason (TARGET_STOPPED_BY_NO_REASON); @@ -2636,8 +2750,8 @@ clear_proceed_status_thread (struct thread_info *tp) { infrun_debug_printf ("thread %s has pending wait status %s (currently_stepping=%d).", - target_pid_to_str (tp->ptid).c_str (), - target_waitstatus_to_string (&tp->pending_waitstatus ()).c_str (), + tp->ptid.to_string ().c_str (), + tp->pending_waitstatus ().to_string ().c_str (), currently_stepping (tp)); } } @@ -2647,8 +2761,7 @@ clear_proceed_status_thread (struct thread_info *tp) if (!signal_pass_state (tp->stop_signal ())) tp->set_stop_signal (GDB_SIGNAL_0); - delete tp->thread_fsm; - tp->thread_fsm = NULL; + tp->release_thread_fsm (); tp->control.trap_expected = 0; tp->control.step_range_start = 0; @@ -3052,7 +3165,6 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) CORE_ADDR pc; struct execution_control_state ecss; struct execution_control_state *ecs = &ecss; - bool started; /* If we're stopped at a fork/vfork, follow the branch set by the "set follow-fork-mode" command; otherwise, we'll just proceed @@ -3179,7 +3291,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) gdb_assert (!thread_is_in_step_over_chain (tp)); infrun_debug_printf ("need to step-over [%s] first", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); global_thread_step_over_chain_enqueue (tp); } @@ -3201,8 +3313,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) { scoped_disable_commit_resumed disable_commit_resumed ("proceeding"); - - started = start_step_over (); + bool step_over_started = start_step_over (); if (step_over_info_valid_p ()) { @@ -3210,7 +3321,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) other thread was already doing one. In either case, don't resume anything else until the step-over is finished. */ } - else if (started && !target_is_non_stop_p ()) + else if (step_over_started && !target_is_non_stop_p ()) { /* A new displaced stepping sequence was started. In all-stop, we can't talk to the target anymore until it next stops. */ @@ -3230,14 +3341,14 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) if (!tp->inf->has_execution ()) { infrun_debug_printf ("[%s] target has no execution", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); continue; } if (tp->resumed ()) { infrun_debug_printf ("[%s] resumed", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); gdb_assert (tp->executing () || tp->has_pending_waitstatus ()); continue; } @@ -3245,12 +3356,25 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) if (thread_is_in_step_over_chain (tp)) { infrun_debug_printf ("[%s] needs step-over", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); + continue; + } + + /* If a thread of that inferior is waiting for a vfork-done + (for a detached vfork child to exec or exit), breakpoints are + removed. We must not resume any thread of that inferior, other + than the one waiting for the vfork-done. */ + if (tp->inf->thread_waiting_for_vfork_done != nullptr + && tp != tp->inf->thread_waiting_for_vfork_done) + { + infrun_debug_printf ("[%s] another thread of this inferior is " + "waiting for vfork-done", + tp->ptid.to_string ().c_str ()); continue; } infrun_debug_printf ("resuming %s", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); reset_ecs (ecs, tp); switch_to_thread (tp); @@ -3259,7 +3383,13 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) error (_("Command aborted.")); } } - else if (!cur_thr->resumed () && !thread_is_in_step_over_chain (cur_thr)) + else if (!cur_thr->resumed () + && !thread_is_in_step_over_chain (cur_thr) + /* In non-stop, forbid resuming a thread if some other thread of + that inferior is waiting for a vfork-done event (this means + breakpoints are out for this inferior). */ + && !(non_stop + && cur_thr->inf->thread_waiting_for_vfork_done != nullptr)) { /* The thread wasn't started, and isn't queued, run it now. */ reset_ecs (ecs, cur_thr); @@ -3475,7 +3605,7 @@ delete_just_stopped_threads_single_step_breakpoints (void) void print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid, - const struct target_waitstatus *ws) + const struct target_waitstatus &ws) { infrun_debug_printf ("target_wait (%s [%s], status) =", waiton_ptid.to_string ().c_str (), @@ -3483,7 +3613,7 @@ print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid, infrun_debug_printf (" %s [%s],", result_ptid.to_string ().c_str (), target_pid_to_str (result_ptid).c_str ()); - infrun_debug_printf (" %s", target_waitstatus_to_string (ws).c_str ()); + infrun_debug_printf (" %s", ws.to_string ().c_str ()); } /* Select a thread at random, out of those which are resumed and have @@ -3502,7 +3632,7 @@ random_pending_event_thread (inferior *inf, ptid_t waiton_ptid) return nullptr; } - infrun_debug_printf ("Found %s.", target_pid_to_str (thread->ptid).c_str ()); + infrun_debug_printf ("Found %s.", thread->ptid.to_string ().c_str ()); gdb_assert (thread->resumed ()); gdb_assert (thread->has_pending_waitstatus ()); @@ -3518,7 +3648,6 @@ static ptid_t do_target_wait_1 (inferior *inf, ptid_t ptid, target_waitstatus *status, target_wait_flags options) { - ptid_t event_ptid; struct thread_info *tp; /* We know that we are looking for an event in the target of inferior @@ -3536,7 +3665,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid, else { infrun_debug_printf ("Waiting for specific thread %s.", - target_pid_to_str (ptid).c_str ()); + ptid.to_string ().c_str ()); /* We have a specific thread to check. */ tp = find_thread_ptid (inf, ptid); @@ -3559,7 +3688,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid, if (pc != tp->stop_pc ()) { infrun_debug_printf ("PC of %s changed. was=%s, now=%s", - target_pid_to_str (tp->ptid).c_str (), + tp->ptid.to_string ().c_str (), paddress (gdbarch, tp->stop_pc ()), paddress (gdbarch, pc)); discard = 1; @@ -3567,7 +3696,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid, else if (!breakpoint_inserted_here_p (regcache->aspace (), pc)) { infrun_debug_printf ("previous breakpoint of %s, at %s gone", - target_pid_to_str (tp->ptid).c_str (), + tp->ptid.to_string ().c_str (), paddress (gdbarch, pc)); discard = 1; @@ -3576,7 +3705,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid, if (discard) { infrun_debug_printf ("pending event of %s cancelled.", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); tp->clear_pending_waitstatus (); target_waitstatus ws; @@ -3589,9 +3718,8 @@ do_target_wait_1 (inferior *inf, ptid_t ptid, if (tp != NULL) { infrun_debug_printf ("Using pending wait status %s for %s.", - target_waitstatus_to_string - (&tp->pending_waitstatus ()).c_str (), - target_pid_to_str (tp->ptid).c_str ()); + tp->pending_waitstatus ().to_string ().c_str (), + tp->ptid.to_string ().c_str ()); /* Now that we've selected our final event LWP, un-adjust its PC if it was a software breakpoint (and the target doesn't @@ -3634,12 +3762,7 @@ do_target_wait_1 (inferior *inf, ptid_t ptid, if (!target_can_async_p ()) options &= ~TARGET_WNOHANG; - if (deprecated_target_wait_hook) - event_ptid = deprecated_target_wait_hook (ptid, status, options); - else - event_ptid = target_wait (ptid, status, options); - - return event_ptid; + return target_wait (ptid, status, options); } /* Wrapper for target_wait that first checks whether threads have @@ -3750,7 +3873,6 @@ struct wait_one_event }; static bool handle_one (const wait_one_event &event); -static void restart_threads (struct thread_info *event_thread); /* Prepare and stabilize the inferior for detaching it. E.g., detaching while a thread is displaced stepping is a recipe for @@ -3775,7 +3897,7 @@ prepare_for_detach (void) if (tp->inf == inf) { infrun_debug_printf ("removing thread %s from global step over chain", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); global_thread_step_over_chain_remove (tp); } @@ -3839,7 +3961,7 @@ prepare_for_detach (void) event.ptid = do_target_wait_1 (inf, pid_ptid, &event.ws, 0); if (debug_infrun) - print_target_wait_results (pid_ptid, event.ptid, &event.ws); + print_target_wait_results (pid_ptid, event.ptid, event.ws); handle_one (event); } @@ -3849,6 +3971,16 @@ prepare_for_detach (void) } } +/* If all-stop, but there exists a non-stop target, stop all threads + now that we're presenting the stop to the user. */ + +static void +stop_all_threads_if_all_stop_mode () +{ + if (!non_stop && exists_non_stop_target ()) + stop_all_threads ("presenting stop to user in all-stop"); +} + /* Wait for control to return from inferior to debugger. If inferior gets a signal, we may decide to start it up again @@ -3886,7 +4018,7 @@ wait_for_inferior (inferior *inf) ecs->target = inf->process_target (); if (debug_infrun) - print_target_wait_results (minus_one_ptid, ecs->ptid, &ecs->ws); + print_target_wait_results (minus_one_ptid, ecs->ptid, ecs->ws); /* Now figure out what to do with the result of the result. */ handle_inferior_event (ecs); @@ -3895,6 +4027,8 @@ wait_for_inferior (inferior *inf) break; } + stop_all_threads_if_all_stop_mode (); + /* No error, don't finish the state yet. */ finish_state.release (); } @@ -3934,25 +4068,29 @@ reinstall_readline_callback_handler_cleanup () static void clean_up_just_stopped_threads_fsms (struct execution_control_state *ecs) { - if (ecs->event_thread != NULL - && ecs->event_thread->thread_fsm != NULL) - ecs->event_thread->thread_fsm->clean_up (ecs->event_thread); + /* The first clean_up call below assumes the event thread is the current + one. */ + if (ecs->event_thread != nullptr) + gdb_assert (ecs->event_thread == inferior_thread ()); + + if (ecs->event_thread != nullptr + && ecs->event_thread->thread_fsm () != nullptr) + ecs->event_thread->thread_fsm ()->clean_up (ecs->event_thread); if (!non_stop) { + scoped_restore_current_thread restore_thread; + for (thread_info *thr : all_non_exited_threads ()) { - if (thr->thread_fsm == NULL) + if (thr->thread_fsm () == nullptr) continue; if (thr == ecs->event_thread) continue; switch_to_thread (thr); - thr->thread_fsm->clean_up (thr); + thr->thread_fsm ()->clean_up (thr); } - - if (ecs->event_thread != NULL) - switch_to_thread (ecs->event_thread); } } @@ -3970,7 +4108,7 @@ check_curr_ui_sync_execution_done (void) { target_terminal::ours (); gdb::observers::sync_execution_done.notify (); - ui_register_input_event_handler (ui); + ui->register_file_handler (); } } @@ -4076,7 +4214,7 @@ fetch_inferior_event () switch_to_target_no_thread (ecs->target); if (debug_infrun) - print_target_wait_results (minus_one_ptid, ecs->ptid, &ecs->ws); + print_target_wait_results (minus_one_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 @@ -4102,13 +4240,8 @@ fetch_inferior_event () delete_just_stopped_threads_infrun_breakpoints (); - if (thr != NULL) - { - struct thread_fsm *thread_fsm = thr->thread_fsm; - - if (thread_fsm != NULL) - should_stop = thread_fsm->should_stop (thr); - } + if (thr != nullptr && thr->thread_fsm () != nullptr) + should_stop = thr->thread_fsm ()->should_stop (thr); if (!should_stop) { @@ -4119,10 +4252,13 @@ fetch_inferior_event () bool should_notify_stop = true; int proceeded = 0; + stop_all_threads_if_all_stop_mode (); + clean_up_just_stopped_threads_fsms (ecs); - if (thr != NULL && thr->thread_fsm != NULL) - should_notify_stop = thr->thread_fsm->should_notify_stop (); + if (thr != nullptr && thr->thread_fsm () != nullptr) + should_notify_stop + = thr->thread_fsm ()->should_notify_stop (); if (should_notify_stop) { @@ -4164,6 +4300,18 @@ fetch_inferior_event () reinstalled here. */ } + /* Handling this event might have caused some inferiors to become prunable. + For example, the exit of an inferior that was automatically added. Try + to get rid of them. Keeping those around slows down things linearly. + + Note that this never removes the current inferior. Therefore, call this + after RESTORE_THREAD went out of scope, in case the event inferior (which was + temporarily made the current inferior) is meant to be deleted. + + Call this before all_uis_check_sync_execution_done, so that notifications about + removed inferiors appear before the prompt. */ + prune_inferiors (); + /* If a UI was in sync execution mode, and now isn't, restore its prompt (a synchronous execution command has finished, and we're ready for input). */ @@ -4173,7 +4321,7 @@ fetch_inferior_event () && exec_done_display_p && (inferior_ptid == null_ptid || inferior_thread ()->state != THREAD_RUNNING)) - printf_unfiltered (_("completed.\n")); + gdb_printf (_("completed.\n")); } /* See infrun.h. */ @@ -4191,6 +4339,13 @@ set_step_info (thread_info *tp, struct frame_info *frame, tp->current_symtab = sal.symtab; tp->current_line = sal.line; + + infrun_debug_printf + ("symtab = %s, line = %d, step_frame_id = %s, step_stack_frame_id = %s", + tp->current_symtab != nullptr ? tp->current_symtab->filename : "", + tp->current_line, + tp->control.step_frame_id.to_string ().c_str (), + tp->control.step_stack_frame_id.to_string ().c_str ()); } /* Clear context switchable stepping state. */ @@ -4249,8 +4404,8 @@ context_switch (execution_control_state *ecs) || ecs->event_thread != inferior_thread ())) { infrun_debug_printf ("Switching context from %s to %s", - target_pid_to_str (inferior_ptid).c_str (), - target_pid_to_str (ecs->ptid).c_str ()); + inferior_ptid.to_string ().c_str (), + ecs->ptid.to_string ().c_str ()); } switch_to_thread (ecs->event_thread); @@ -4263,7 +4418,7 @@ context_switch (execution_control_state *ecs) static void adjust_pc_after_break (struct thread_info *thread, - const target_waitstatus *ws) + const target_waitstatus &ws) { struct regcache *regcache; struct gdbarch *gdbarch; @@ -4290,10 +4445,10 @@ adjust_pc_after_break (struct thread_info *thread, target with both of these set in GDB history, and it seems unlikely to be correct, so gdbarch_have_nonsteppable_watchpoint is not checked here. */ - if (ws->kind () != TARGET_WAITKIND_STOPPED) + if (ws.kind () != TARGET_WAITKIND_STOPPED) return; - if (ws->sig () != GDB_SIGNAL_TRAP) + if (ws.sig () != GDB_SIGNAL_TRAP) return; /* In reverse execution, when a breakpoint is hit, the instruction @@ -4498,9 +4653,9 @@ handle_syscall_event (struct execution_control_state *ecs) infrun_debug_printf ("syscall number=%d", syscall_number); ecs->event_thread->control.stop_bpstat - = bpstat_stop_status (regcache->aspace (), - ecs->event_thread->stop_pc (), - ecs->event_thread, &ecs->ws); + = bpstat_stop_status_nowatch (regcache->aspace (), + ecs->event_thread->stop_pc (), + ecs->event_thread, ecs->ws); if (handle_stop_requested (ecs)) return false; @@ -4550,8 +4705,8 @@ fill_in_stop_func (struct gdbarch *gdbarch, 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 <= block->entry_pc () + && block->entry_pc () < ecs->stop_func_end) { ecs->stop_func_start += gdbarch_deprecated_function_start_offset (gdbarch); @@ -4593,13 +4748,10 @@ poll_one_curr_target (struct target_waitstatus *ws) don't get any event. */ target_dcache_invalidate (); - if (deprecated_target_wait_hook) - event_ptid = deprecated_target_wait_hook (minus_one_ptid, ws, TARGET_WNOHANG); - else - event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG); + event_ptid = target_wait (minus_one_ptid, ws, TARGET_WNOHANG); if (debug_infrun) - print_target_wait_results (minus_one_ptid, event_ptid, ws); + print_target_wait_results (minus_one_ptid, event_ptid, *ws); return event_ptid; } @@ -4629,7 +4781,7 @@ wait_one () { /* If nothing is resumed, remove the target from the event loop. */ - target_async (0); + target_async (false); } else if (event.ws.kind () != TARGET_WAITKIND_IGNORE) return event; @@ -4680,23 +4832,23 @@ wait_one () /* Save the thread's event and stop reason to process it later. */ static void -save_waitstatus (struct thread_info *tp, const target_waitstatus *ws) +save_waitstatus (struct thread_info *tp, const target_waitstatus &ws) { infrun_debug_printf ("saving status %s for %s", - target_waitstatus_to_string (ws).c_str (), + ws.to_string ().c_str (), tp->ptid.to_string ().c_str ()); /* Record for later. */ - tp->set_pending_waitstatus (*ws); + tp->set_pending_waitstatus (ws); - if (ws->kind () == TARGET_WAITKIND_STOPPED - && ws->sig () == GDB_SIGNAL_TRAP) + if (ws.kind () == TARGET_WAITKIND_STOPPED + && ws.sig () == GDB_SIGNAL_TRAP) { struct regcache *regcache = get_thread_regcache (tp); const address_space *aspace = regcache->aspace (); CORE_ADDR pc = regcache_read_pc (regcache); - adjust_pc_after_break (tp, &tp->pending_waitstatus ()); + adjust_pc_after_break (tp, tp->pending_waitstatus ()); scoped_restore_current_thread restore_thread; switch_to_thread (tp); @@ -4774,8 +4926,8 @@ static bool handle_one (const wait_one_event &event) { infrun_debug_printf - ("%s %s", target_waitstatus_to_string (&event.ws).c_str (), - target_pid_to_str (event.ptid).c_str ()); + ("%s %s", event.ws.to_string ().c_str (), + event.ptid.to_string ().c_str ()); if (event.ws.kind () == TARGET_WAITKIND_NO_RESUMED) { @@ -4811,7 +4963,7 @@ handle_one (const wait_one_event &event) gdb_assert (t != nullptr); infrun_debug_printf - ("using %s", target_pid_to_str (t->ptid).c_str ()); + ("using %s", t->ptid.to_string ().c_str ()); } else { @@ -4830,7 +4982,7 @@ handle_one (const wait_one_event &event) switch_to_thread_no_regs (t); mark_non_executing_threads (event.target, event.ptid, event.ws); - save_waitstatus (t, &event.ws); + save_waitstatus (t, event.ws); t->stop_requested = false; } } @@ -4847,8 +4999,7 @@ handle_one (const wait_one_event &event) /* This may be the first time we see the inferior report a stop. */ - inferior *inf = find_inferior_ptid (event.target, event.ptid); - if (inf->needs_setup) + if (t->inf->needs_setup) { switch_to_thread_no_regs (t); setup_inferior (0); @@ -4866,7 +5017,7 @@ handle_one (const wait_one_event &event) /* Add it back to the step-over queue. */ infrun_debug_printf ("displaced-step of %s canceled", - target_pid_to_str (t->ptid).c_str ()); + t->ptid.to_string ().c_str ()); t->control.trap_expected = 0; if (!t->inf->detaching) @@ -4880,11 +5031,11 @@ handle_one (const wait_one_event &event) infrun_debug_printf ("target_wait %s, saving status for %s", - target_waitstatus_to_string (&event.ws).c_str (), + event.ws.to_string ().c_str (), t->ptid.to_string ().c_str ()); /* Record for later. */ - save_waitstatus (t, &event.ws); + save_waitstatus (t, event.ws); sig = (event.ws.kind () == TARGET_WAITKIND_STOPPED ? event.ws.sig () : GDB_SIGNAL_0); @@ -4904,7 +5055,7 @@ handle_one (const wait_one_event &event) infrun_debug_printf ("saved stop_pc=%s for %s " "(currently_stepping=%d)", paddress (target_gdbarch (), t->stop_pc ()), - target_pid_to_str (t->ptid).c_str (), + t->ptid.to_string ().c_str (), currently_stepping (t)); } } @@ -4915,7 +5066,7 @@ handle_one (const wait_one_event &event) /* See infrun.h. */ void -stop_all_threads (void) +stop_all_threads (const char *reason, inferior *inf) { /* We may need multiple passes to discover all threads. */ int pass; @@ -4923,22 +5074,32 @@ stop_all_threads (void) gdb_assert (exists_non_stop_target ()); - infrun_debug_printf ("starting"); + INFRUN_SCOPED_DEBUG_START_END ("reason=%s, inf=%d", reason, + inf != nullptr ? inf->num : -1); + + infrun_debug_show_threads ("non-exited threads", + all_non_exited_threads ()); scoped_restore_current_thread restore_thread; - /* Enable thread events of all targets. */ + /* Enable thread events on relevant targets. */ for (auto *target : all_non_exited_process_targets ()) { + if (inf != nullptr && inf->process_target () != target) + continue; + switch_to_target_no_thread (target); target_thread_events (true); } SCOPE_EXIT { - /* Disable thread events of all targets. */ + /* Disable thread events on relevant targets. */ for (auto *target : all_non_exited_process_targets ()) { + if (inf != nullptr && inf->process_target () != target) + continue; + switch_to_target_no_thread (target); target_thread_events (false); } @@ -4963,6 +5124,9 @@ stop_all_threads (void) for (auto *target : all_non_exited_process_targets ()) { + if (inf != nullptr && inf->process_target () != target) + continue; + switch_to_target_no_thread (target); update_thread_list (); } @@ -4971,6 +5135,9 @@ stop_all_threads (void) to tell the target to stop. */ for (thread_info *t : all_non_exited_threads ()) { + if (inf != nullptr && t->inf != inf) + continue; + /* For a single-target setting with an all-stop target, we would not even arrive here. For a multi-target setting, until GDB is able to handle a mixture of @@ -4989,14 +5156,14 @@ stop_all_threads (void) if (!t->stop_requested) { infrun_debug_printf (" %s executing, need stop", - target_pid_to_str (t->ptid).c_str ()); + t->ptid.to_string ().c_str ()); target_stop (t->ptid); t->stop_requested = 1; } else { infrun_debug_printf (" %s executing, already stopping", - target_pid_to_str (t->ptid).c_str ()); + t->ptid.to_string ().c_str ()); } if (t->stop_requested) @@ -5005,7 +5172,7 @@ stop_all_threads (void) else { infrun_debug_printf (" %s not executing", - target_pid_to_str (t->ptid).c_str ()); + t->ptid.to_string ().c_str ()); /* The thread may be not executing, but still be resumed with a pending status to process. */ @@ -5098,12 +5265,7 @@ handle_no_resumed (struct execution_control_state *ecs) inferior *curr_inf = current_inferior (); scoped_restore_current_thread restore_thread; - - for (auto *target : all_non_exited_process_targets ()) - { - switch_to_target_no_thread (target); - update_thread_list (); - } + update_thread_list (); /* If: @@ -5138,8 +5300,7 @@ handle_no_resumed (struct execution_control_state *ecs) swap_terminal = false; } - if (!ignore_event - && (thread->executing () || thread->has_pending_waitstatus ())) + if (!ignore_event && thread->resumed ()) { /* Either there were no unwaited-for children left in the target at some point, but there are now, or some target @@ -5187,7 +5348,7 @@ handle_inferior_event (struct execution_control_state *ecs) end. */ scoped_value_mark free_values; - infrun_debug_printf ("%s", target_waitstatus_to_string (&ecs->ws).c_str ()); + infrun_debug_printf ("%s", ecs->ws.to_string ().c_str ()); if (ecs->ws.kind () == TARGET_WAITKIND_IGNORE) { @@ -5243,7 +5404,7 @@ handle_inferior_event (struct execution_control_state *ecs) } /* Dependent on valid ECS->EVENT_THREAD. */ - adjust_pc_after_break (ecs->event_thread, &ecs->ws); + adjust_pc_after_break (ecs->event_thread, ecs->ws); /* Dependent on the current PC value modified by adjust_pc_after_break. */ reinit_frame_cache (); @@ -5300,9 +5461,9 @@ handle_inferior_event (struct execution_control_state *ecs) ecs->event_thread->set_stop_pc (regcache_read_pc (regcache)); ecs->event_thread->control.stop_bpstat - = bpstat_stop_status (regcache->aspace (), - ecs->event_thread->stop_pc (), - ecs->event_thread, &ecs->ws); + = bpstat_stop_status_nowatch (regcache->aspace (), + ecs->event_thread->stop_pc (), + ecs->event_thread, ecs->ws); if (handle_stop_requested (ecs)) return; @@ -5543,9 +5704,9 @@ handle_inferior_event (struct execution_control_state *ecs) (regcache_read_pc (get_thread_regcache (ecs->event_thread))); ecs->event_thread->control.stop_bpstat - = bpstat_stop_status (get_current_regcache ()->aspace (), - ecs->event_thread->stop_pc (), - ecs->event_thread, &ecs->ws); + = bpstat_stop_status_nowatch (get_current_regcache ()->aspace (), + ecs->event_thread->stop_pc (), + ecs->event_thread, ecs->ws); if (handle_stop_requested (ecs)) return; @@ -5605,7 +5766,18 @@ handle_inferior_event (struct execution_control_state *ecs) ecs->ptid = inferior_ptid; if (should_resume) - keep_going (ecs); + { + /* Never call switch_back_to_stepped_thread if we are waiting for + vfork-done (waiting for an external vfork child to exec or + exit). We will resume only the vforking thread for the purpose + of collecting the vfork-done event, and we will restart any + step once the critical shared address space window is done. */ + if ((!follow_child + && detach_fork + && parent->inf->thread_waiting_for_vfork_done != nullptr) + || !switch_back_to_stepped_thread (ecs)) + keep_going (ecs); + } else stop_waiting (ecs); return; @@ -5619,15 +5791,19 @@ handle_inferior_event (struct execution_control_state *ecs) context_switch (ecs); - current_inferior ()->waiting_for_vfork_done = 0; - current_inferior ()->pspace->breakpoints_not_allowed = 0; + handle_vfork_done (ecs->event_thread); + gdb_assert (inferior_thread () == ecs->event_thread); if (handle_stop_requested (ecs)) return; - /* This also takes care of reinserting breakpoints in the - previously locked inferior. */ - keep_going (ecs); + if (!switch_back_to_stepped_thread (ecs)) + { + gdb_assert (inferior_thread () == ecs->event_thread); + /* This also takes care of reinserting breakpoints in the + previously locked inferior. */ + keep_going (ecs); + } return; case TARGET_WAITKIND_EXECD: @@ -5654,9 +5830,9 @@ handle_inferior_event (struct execution_control_state *ecs) (regcache_read_pc (get_thread_regcache (ecs->event_thread))); ecs->event_thread->control.stop_bpstat - = bpstat_stop_status (get_current_regcache ()->aspace (), - ecs->event_thread->stop_pc (), - ecs->event_thread, &ecs->ws); + = bpstat_stop_status_nowatch (get_current_regcache ()->aspace (), + ecs->event_thread->stop_pc (), + ecs->event_thread, ecs->ws); if (handle_stop_requested (ecs)) return; @@ -5714,21 +5890,32 @@ handle_inferior_event (struct execution_control_state *ecs) } /* 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. */ + paused them (because of an in-line step-over or vfork, for example). + The EVENT_THREAD thread is ignored (not restarted). + + If INF is non-nullptr, only resume threads from INF. */ static void -restart_threads (struct thread_info *event_thread) +restart_threads (struct thread_info *event_thread, inferior *inf) { + INFRUN_SCOPED_DEBUG_START_END ("event_thread=%s, inf=%d", + event_thread->ptid.to_string ().c_str (), + inf != nullptr ? inf->num : -1); + + gdb_assert (!step_over_info_valid_p ()); + /* In case the instruction just stepped spawned a new thread. */ update_thread_list (); for (thread_info *tp : all_non_exited_threads ()) { + if (inf != nullptr && tp->inf != inf) + continue; + if (tp->inf->detaching) { infrun_debug_printf ("restart threads: [%s] inferior detaching", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); continue; } @@ -5737,21 +5924,21 @@ restart_threads (struct thread_info *event_thread) if (tp == event_thread) { infrun_debug_printf ("restart threads: [%s] is event thread", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); continue; } if (!(tp->state == THREAD_RUNNING || tp->control.in_infcall)) { infrun_debug_printf ("restart threads: [%s] not meant to be running", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); continue; } if (tp->resumed ()) { infrun_debug_printf ("restart threads: [%s] resumed", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); gdb_assert (tp->executing () || tp->has_pending_waitstatus ()); continue; } @@ -5759,7 +5946,7 @@ restart_threads (struct thread_info *event_thread) if (thread_is_in_step_over_chain (tp)) { infrun_debug_printf ("restart threads: [%s] needs step-over", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); gdb_assert (!tp->resumed ()); continue; } @@ -5768,7 +5955,7 @@ restart_threads (struct thread_info *event_thread) if (tp->has_pending_waitstatus ()) { infrun_debug_printf ("restart threads: [%s] has pending status", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); tp->set_resumed (true); continue; } @@ -5783,13 +5970,13 @@ restart_threads (struct thread_info *event_thread) internal_error (__FILE__, __LINE__, "thread [%s] needs a step-over, but not in " "step-over queue\n", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); } if (currently_stepping (tp)) { infrun_debug_printf ("restart threads: [%s] was stepping", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); keep_going_stepped_thread (tp); } else @@ -5798,7 +5985,7 @@ restart_threads (struct thread_info *event_thread) struct execution_control_state *ecs = &ecss; infrun_debug_printf ("restart threads: [%s] continuing", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); reset_ecs (ecs, tp); switch_to_thread (tp); keep_going_pass_signal (ecs); @@ -5893,7 +6080,7 @@ finish_step_over (struct execution_control_state *ecs) gdb_assert (pending != tp); /* Record the event thread's event for later. */ - save_waitstatus (tp, &ecs->ws); + save_waitstatus (tp, ecs->ws); /* This was cleared early, by handle_inferior_event. Set it so this pending event is considered by do_target_wait. */ @@ -5907,7 +6094,7 @@ finish_step_over (struct execution_control_state *ecs) infrun_debug_printf ("saved stop_pc=%s for %s " "(currently_stepping=%d)", paddress (target_gdbarch (), tp->stop_pc ()), - target_pid_to_str (tp->ptid).c_str (), + tp->ptid.to_string ().c_str (), currently_stepping (tp)); /* This in-line step-over finished; clear this so we won't @@ -6051,14 +6238,14 @@ handle_signal_stop (struct execution_control_state *ecs) { infrun_debug_printf ("[%s] hit another thread's single-step " "breakpoint", - target_pid_to_str (ecs->ptid).c_str ()); + ecs->ptid.to_string ().c_str ()); ecs->hit_singlestep_breakpoint = 1; } } else { infrun_debug_printf ("[%s] hit its single-step breakpoint", - target_pid_to_str (ecs->ptid).c_str ()); + ecs->ptid.to_string ().c_str ()); } } delete_just_stopped_threads_single_step_breakpoints (); @@ -6068,7 +6255,7 @@ handle_signal_stop (struct execution_control_state *ecs) && ecs->event_thread->stepping_over_watchpoint) stopped_by_watchpoint = 0; else - stopped_by_watchpoint = watchpoints_triggered (&ecs->ws); + stopped_by_watchpoint = watchpoints_triggered (ecs->ws); /* If necessary, step over this watchpoint. We'll be back to display it in a moment. */ @@ -6114,7 +6301,7 @@ handle_signal_stop (struct execution_control_state *ecs) ecs->event_thread->control.stop_step = 0; stop_print_frame = true; stopped_by_random_signal = 0; - bpstat stop_chain = NULL; + bpstat *stop_chain = nullptr; /* Hide inlined functions starting here, unless we just performed stepi or nexti. After stepi and nexti, always show the innermost frame (not any @@ -6141,16 +6328,16 @@ handle_signal_stop (struct execution_control_state *ecs) that's an extremely unlikely scenario. */ if (!pc_at_non_inline_function (aspace, ecs->event_thread->stop_pc (), - &ecs->ws) + ecs->ws) && !(ecs->event_thread->stop_signal () == GDB_SIGNAL_TRAP && ecs->event_thread->control.trap_expected && pc_at_non_inline_function (aspace, ecs->event_thread->prev_pc, - &ecs->ws))) + ecs->ws))) { stop_chain = build_bpstat_chain (aspace, ecs->event_thread->stop_pc (), - &ecs->ws); + ecs->ws); skip_inline_frames (ecs->event_thread, stop_chain); /* Re-fetch current thread's frame in case that invalidated @@ -6202,7 +6389,7 @@ handle_signal_stop (struct execution_control_state *ecs) ecs->event_thread->control.stop_bpstat = bpstat_stop_status (get_current_regcache ()->aspace (), ecs->event_thread->stop_pc (), - ecs->event_thread, &ecs->ws, stop_chain); + ecs->event_thread, ecs->ws, stop_chain); /* Following in case break condition called a function. */ @@ -7266,6 +7453,11 @@ process_event_stop_test (struct execution_control_state *ecs) ecs->event_thread->control.step_range_start = stop_pc_sal.pc; ecs->event_thread->control.step_range_end = stop_pc_sal.end; ecs->event_thread->control.may_range_step = 1; + infrun_debug_printf + ("updated step range, start = %s, end = %s, may_range_step = %d", + paddress (gdbarch, ecs->event_thread->control.step_range_start), + paddress (gdbarch, ecs->event_thread->control.step_range_end), + ecs->event_thread->control.may_range_step); if (refresh_step_info) set_step_info (ecs->event_thread, frame, stop_pc_sal); @@ -7304,7 +7496,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs) { infrun_debug_printf ("need to finish step-over of [%s]", - target_pid_to_str (ecs->event_thread->ptid).c_str ()); + ecs->event_thread->ptid.to_string ().c_str ()); keep_going (ecs); return true; } @@ -7314,7 +7506,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs) if (ecs->hit_singlestep_breakpoint) { infrun_debug_printf ("need to step [%s] over single-step breakpoint", - target_pid_to_str (ecs->ptid).c_str ()); + ecs->ptid.to_string ().c_str ()); keep_going (ecs); return true; } @@ -7326,7 +7518,7 @@ switch_back_to_stepped_thread (struct execution_control_state *ecs) { infrun_debug_printf ("thread [%s] still needs step-over", - target_pid_to_str (ecs->event_thread->ptid).c_str ()); + ecs->event_thread->ptid.to_string ().c_str ()); keep_going (ecs); return true; } @@ -7932,10 +8124,10 @@ check_exception_resume (struct execution_control_state *ecs, cases such as throwing an exception from inside a signal handler. */ - b = SYMBOL_BLOCK_VALUE (func); + b = func->value_block (); ALL_BLOCK_SYMBOLS (b, iter, sym) { - if (!SYMBOL_IS_ARGUMENT (sym)) + if (!sym->is_argument ()) continue; if (argno == 0) @@ -7960,11 +8152,6 @@ stop_waiting (struct execution_control_state *ecs) /* Let callers know we don't want to wait for the inferior anymore. */ ecs->wait_some_more = 0; - - /* If all-stop, but there exists a non-stop target, stop all - threads now that we're presenting the stop to the user. */ - if (!non_stop && exists_non_stop_target ()) - stop_all_threads (); } /* Like keep_going, but passes the signal to the inferior, even if the @@ -7986,7 +8173,7 @@ keep_going_pass_signal (struct execution_control_state *ecs) infrun_debug_printf ("%s has trap_expected set, " "resuming to collect trap", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().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 @@ -8006,14 +8193,12 @@ keep_going_pass_signal (struct execution_control_state *ecs) { infrun_debug_printf ("step-over already in progress: " "step-over for %s deferred", - target_pid_to_str (tp->ptid).c_str ()); + tp->ptid.to_string ().c_str ()); global_thread_step_over_chain_enqueue (tp); } else - { - infrun_debug_printf ("step-over in progress: resume of %s deferred", - target_pid_to_str (tp->ptid).c_str ()); - } + infrun_debug_printf ("step-over in progress: resume of %s deferred", + tp->ptid.to_string ().c_str ()); } else { @@ -8066,7 +8251,7 @@ keep_going_pass_signal (struct execution_control_state *ecs) we're about to step over, otherwise other threads could miss it. */ if (step_over_info_valid_p () && target_is_non_stop_p ()) - stop_all_threads (); + stop_all_threads ("starting in-line step-over"); /* Stop stepping if inserting breakpoints fails. */ try @@ -8267,14 +8452,14 @@ print_no_history_reason (struct ui_out *uiout) based on the event(s) that just occurred. */ static void -print_stop_location (struct target_waitstatus *ws) +print_stop_location (const target_waitstatus &ws) { int bpstat_ret; enum print_what source_flag; int do_frame_printing = 1; struct thread_info *tp = inferior_thread (); - bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws->kind ()); + bpstat_ret = bpstat_print (tp->control.stop_bpstat, ws.kind ()); switch (bpstat_ret) { case PRINT_UNKNOWN: @@ -8334,7 +8519,7 @@ print_stop_event (struct ui_out *uiout, bool displays) { scoped_restore save_uiout = make_scoped_restore (¤t_uiout, uiout); - print_stop_location (&last); + print_stop_location (last); /* Display the auto-display expressions. */ if (displays) @@ -8342,13 +8527,13 @@ print_stop_event (struct ui_out *uiout, bool displays) } tp = inferior_thread (); - if (tp->thread_fsm != NULL - && tp->thread_fsm->finished_p ()) + if (tp->thread_fsm () != nullptr + && tp->thread_fsm ()->finished_p ()) { struct return_value_info *rv; - rv = tp->thread_fsm->return_value (); - if (rv != NULL) + rv = tp->thread_fsm ()->return_value (); + if (rv != nullptr) print_return_value (uiout, rv); } } @@ -8363,9 +8548,9 @@ maybe_remove_breakpoints (void) if (remove_breakpoints ()) { target_terminal::ours_for_output (); - printf_filtered (_("Cannot remove breakpoints because " - "program is no longer writable.\nFurther " - "execution is probably impossible.\n")); + gdb_printf (_("Cannot remove breakpoints because " + "program is no longer writable.\nFurther " + "execution is probably impossible.\n")); } } } @@ -8509,8 +8694,8 @@ normal_stop (void) SWITCH_THRU_ALL_UIS () { target_terminal::ours_for_output (); - printf_filtered (_("[Switching to %s]\n"), - target_pid_to_str (inferior_ptid).c_str ()); + gdb_printf (_("[Switching to %s]\n"), + target_pid_to_str (inferior_ptid).c_str ()); annotate_thread_changed (); } previous_inferior_ptid = inferior_ptid; @@ -8522,7 +8707,7 @@ normal_stop (void) if (current_ui->prompt_state == PROMPT_BLOCKED) { target_terminal::ours_for_output (); - printf_filtered (_("No unwaited-for children left.\n")); + gdb_printf (_("No unwaited-for children left.\n")); } } @@ -8573,29 +8758,26 @@ normal_stop (void) /* Look up the hook_stop and run it (CLI internally handles problem of stop_command's pre-hook not existing). */ - if (stop_command != NULL) - { - stop_context saved_context; + stop_context saved_context; - try - { - execute_cmd_pre_hook (stop_command); - } - catch (const gdb_exception &ex) - { - exception_fprintf (gdb_stderr, ex, - "Error while running hook_stop:\n"); - } - - /* If the stop hook resumes the target, then there's no point in - trying to notify about the previous stop; its context is - gone. Likewise if the command switches thread or inferior -- - the observers would print a stop for the wrong - thread/inferior. */ - if (saved_context.changed ()) - return 1; + try + { + execute_cmd_pre_hook (stop_command); + } + catch (const gdb_exception &ex) + { + exception_fprintf (gdb_stderr, ex, + "Error while running hook_stop:\n"); } + /* If the stop hook resumes the target, then there's no point in + trying to notify about the previous stop; its context is + gone. Likewise if the command switches thread or inferior -- + the observers would print a stop for the wrong + thread/inferior. */ + if (saved_context.changed ()) + return 1; + /* Notify observers about the stop. This is where the interpreters print the stop event. */ if (inferior_ptid != null_ptid) @@ -8616,11 +8798,6 @@ normal_stop (void) breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat); } - /* Try to get rid of automatically added inferiors that are no - longer needed. Keeping those around slows down things linearly. - Note that this never removes the current inferior. */ - prune_inferiors (); - return 0; } @@ -8706,8 +8883,8 @@ signal_catch_update (const unsigned int *info) static void sig_print_header (void) { - printf_filtered (_("Signal Stop\tPrint\tPass " - "to program\tDescription\n")); + gdb_printf (_("Signal Stop\tPrint\tPass " + "to program\tDescription\n")); } static void @@ -8719,12 +8896,12 @@ sig_print_info (enum gdb_signal oursig) if (name_padding <= 0) name_padding = 0; - printf_filtered ("%s", name); - printf_filtered ("%*.*s ", name_padding, name_padding, " "); - printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No"); - printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No"); - printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No"); - printf_filtered ("%s\n", gdb_signal_to_string (oursig)); + gdb_printf ("%s", name); + gdb_printf ("%*.*s ", name_padding, name_padding, " "); + gdb_printf ("%s\t", signal_stop[oursig] ? "Yes" : "No"); + gdb_printf ("%s\t", signal_print[oursig] ? "Yes" : "No"); + gdb_printf ("%s\t\t", signal_program[oursig] ? "Yes" : "No"); + gdb_printf ("%s\n", gdb_signal_to_string (oursig)); } /* Specify how various signals in the inferior should be handled. */ @@ -8860,7 +9037,7 @@ Are you sure you want to change it? "), sigs[signum] = 1; } else - printf_unfiltered (_("Not confirmed, unchanged.\n")); + gdb_printf (_("Not confirmed, unchanged.\n")); } break; case GDB_SIGNAL_0: @@ -8955,7 +9132,7 @@ info_signals_command (const char *signum_exp, int from_tty) return; } - printf_filtered ("\n"); + gdb_printf ("\n"); /* These ugly casts brought to you by the native VAX compiler. */ for (oursig = GDB_SIGNAL_FIRST; (int) oursig < (int) GDB_SIGNAL_LAST; @@ -8968,8 +9145,8 @@ info_signals_command (const char *signum_exp, int from_tty) sig_print_info (oursig); } - printf_filtered (_("\nUse the \"handle\" command " - "to change these tables.\n")); + gdb_printf (_("\nUse the \"handle\" command " + "to change these tables.\n")); } /* The $_siginfo convenience variable is a bit special. We don't know @@ -8998,7 +9175,7 @@ siginfo_value_read (struct value *v) target_read (current_inferior ()->top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL, - value_contents_all_raw (v), + value_contents_all_raw (v).data (), value_offset (v), TYPE_LENGTH (value_type (v))); @@ -9021,7 +9198,7 @@ siginfo_value_write (struct value *v, struct value *fromval) transferred = target_write (current_inferior ()->top_target (), TARGET_OBJECT_SIGNAL_INFO, NULL, - value_contents_all_raw (fromval), + value_contents_all_raw (fromval).data (), value_offset (v), TYPE_LENGTH (value_type (fromval))); @@ -9342,10 +9519,10 @@ show_exec_direction_func (struct ui_file *out, int from_tty, { switch (execution_direction) { case EXEC_FORWARD: - fprintf_filtered (out, _("Forward.\n")); + gdb_printf (out, _("Forward.\n")); break; case EXEC_REVERSE: - fprintf_filtered (out, _("Reverse.\n")); + gdb_printf (out, _("Reverse.\n")); break; default: internal_error (__FILE__, __LINE__, @@ -9358,8 +9535,8 @@ static void show_schedule_multiple (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - fprintf_filtered (file, _("Resuming the execution of threads " - "of all processes is %s.\n"), value); + gdb_printf (file, _("Resuming the execution of threads " + "of all processes is %s.\n"), value); } /* Implementation of `siginfo' variable. */ @@ -9368,7 +9545,6 @@ static const struct internalvar_funcs siginfo_funcs = { siginfo_make_value, NULL, - NULL }; /* Callback for infrun's target events source. This is marked when a @@ -9499,9 +9675,8 @@ may be interspersed with actions, with the actions being performed for\n\ all signals cumulatively specified.")); set_cmd_completer (c, handle_completer); - if (!dbx_commands) - stop_command = add_cmd ("stop", class_obscure, - not_just_help_class_command, _("\ + stop_command = add_cmd ("stop", class_obscure, + not_just_help_class_command, _("\ There is no `stop' command, but you can set a hook on `stop'.\n\ This allows you to set a list of commands to be run each time execution\n\ of the program stops."), &cmdlist);