diff options
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index ec78148..2068a2a 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1780,6 +1780,7 @@ resume (int step, enum gdb_signal sig) CORE_ADDR pc = regcache_read_pc (regcache); struct address_space *aspace = get_regcache_aspace (regcache); ptid_t resume_ptid; + int hw_step = step; QUIT; @@ -1799,7 +1800,7 @@ resume (int step, enum gdb_signal sig) if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: resume : clear step\n"); - step = 0; + hw_step = 0; } if (debug_infrun) @@ -1844,7 +1845,7 @@ a command like `return' or `jump' to continue execution.")); step software breakpoint. */ if (use_displaced_stepping (gdbarch) && (tp->control.trap_expected - || (step && gdbarch_software_single_step_p (gdbarch))) + || (hw_step && gdbarch_software_single_step_p (gdbarch))) && sig == GDB_SIGNAL_0 && !current_inferior ()->waiting_for_vfork_done) { @@ -1854,11 +1855,14 @@ a command like `return' or `jump' to continue execution.")); { /* Got placed in displaced stepping queue. Will be resumed later when all the currently queued displaced stepping - requests finish. The thread is not executing at this point, - and the call to set_executing will be made later. But we - need to call set_running here, since from frontend point of view, - the thread is running. */ - set_running (inferior_ptid, 1); + requests finish. The thread is not executing at this + point, and the call to set_executing will be made later. + But we need to call set_running here, since from the + user/frontend's point of view, threads were set running. + Unless we're calling an inferior function, as in that + case we pretend the inferior doesn't run at all. */ + if (!tp->control.in_infcall) + set_running (user_visible_resume_ptid (step), 1); discard_cleanups (old_cleanups); return; } @@ -1868,8 +1872,8 @@ a command like `return' or `jump' to continue execution.")); pc = regcache_read_pc (get_thread_regcache (inferior_ptid)); displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid)); - step = gdbarch_displaced_step_hw_singlestep (gdbarch, - displaced->step_closure); + hw_step = gdbarch_displaced_step_hw_singlestep (gdbarch, + displaced->step_closure); } /* Do we need to do it the hard way, w/temp breakpoints? */ @@ -1933,6 +1937,14 @@ a command like `return' or `jump' to continue execution.")); by applying increasingly restricting conditions. */ resume_ptid = user_visible_resume_ptid (step); + /* Even if RESUME_PTID is a wildcard, and we end up resuming less + (e.g., we might need to step over a breakpoint), from the + user/frontend's point of view, all threads in RESUME_PTID are now + running. Unless we're calling an inferior function, as in that + case pretend we inferior doesn't run at all. */ + if (!tp->control.in_infcall) + set_running (resume_ptid, 1); + /* Maybe resume a single thread after all. */ if ((step || singlestep_breakpoints_inserted_p) && tp->control.trap_expected) @@ -6188,8 +6200,18 @@ normal_stop (void) if (has_stack_frames () && !stop_stack_dummy) set_current_sal_from_frame (get_current_frame ()); - /* Let the user/frontend see the threads as stopped. */ - do_cleanups (old_chain); + /* Let the user/frontend see the threads as stopped, but do nothing + if the thread was running an infcall. We may be e.g., evaluating + a breakpoint condition. In that case, the thread had state + THREAD_RUNNING before the infcall, and shall remain set to + running, all without informing the user/frontend about state + transition changes. If this is actually a call command, then the + thread was originally already stopped, so there's no state to + finish either. */ + if (target_has_execution && inferior_thread ()->control.in_infcall) + discard_cleanups (old_chain); + else + do_cleanups (old_chain); /* Look up the hook_stop and run it (CLI internally handles problem of stop_command's pre-hook not existing). */ |