diff options
author | Jim Ingham <jingham@apple.com> | 2019-03-01 18:13:38 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2019-03-01 18:13:38 +0000 |
commit | 3139fc976795c1cb29c46b4c5cb7c571e619a73c (patch) | |
tree | cef747669300658cba860bea52640587bb13c455 /lldb/source/Target/Target.cpp | |
parent | 21f7c35df1de6c2b16aa663e26cb4d09099118a2 (diff) | |
download | bcm5719-llvm-3139fc976795c1cb29c46b4c5cb7c571e619a73c.tar.gz bcm5719-llvm-3139fc976795c1cb29c46b4c5cb7c571e619a73c.zip |
Resubmit r354706 with a fix for process launch.
When the debugger is run in sync mode, you need to
be able to tell whether a hijacked resume is for some
special purpose (like waiting for the SIGSTOP on attach)
or just to perform a synchronous resume. Target::Launch was doing
that wrong, and that caused stop-hooks on process launch
in source files to behave incorrectly.
<rdar://problem/48115661>
Differential Revision: https://reviews.llvm.org/D58727
llvm-svn: 355213
Diffstat (limited to 'lldb/source/Target/Target.cpp')
-rw-r--r-- | lldb/source/Target/Target.cpp | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index f581f073cde..a60ec516280 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2554,12 +2554,14 @@ void Target::RunStopHooks() { StopHookCollection::iterator pos, end = m_stop_hooks.end(); - // If there aren't any active stop hooks, don't bother either: + // If there aren't any active stop hooks, don't bother either. + // Also see if any of the active hooks want to auto-continue. bool any_active_hooks = false; - for (pos = m_stop_hooks.begin(); pos != end; pos++) { - if ((*pos).second->IsActive()) { + bool auto_continue = false; + for (auto hook : m_stop_hooks) { + if (hook.second->IsActive()) { any_active_hooks = true; - break; + auto_continue |= hook.second->GetAutoContinue(); } } if (!any_active_hooks) @@ -2595,6 +2597,7 @@ void Target::RunStopHooks() { bool hooks_ran = false; bool print_hook_header = (m_stop_hooks.size() != 1); bool print_thread_header = (num_exe_ctx != 1); + bool did_restart = false; for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) { // result.Clear(); @@ -2639,10 +2642,13 @@ void Target::RunStopHooks() { options.SetPrintResults(true); options.SetAddToHistory(false); + // Force Async: + bool old_async = GetDebugger().GetAsyncExecution(); + GetDebugger().SetAsyncExecution(true); GetDebugger().GetCommandInterpreter().HandleCommands( cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options, result); - + GetDebugger().SetAsyncExecution(old_async); // If the command started the target going again, we should bag out of // running the stop hooks. if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || @@ -2651,13 +2657,19 @@ void Target::RunStopHooks() { StopHookCollection::iterator tmp = pos; if (++tmp != end) result.AppendMessageWithFormat("\nAborting stop hooks, hook %" PRIu64 - " set the program running.\n", + " set the program running.\n" + " Consider using '-G true' to make " + "stop hooks auto-continue.\n", cur_hook_sp->GetID()); keep_going = false; + did_restart = true; } } } } + // Finally, if auto-continue was requested, do it now: + if (!did_restart && auto_continue) + m_process_sp->PrivateResume(); result.GetImmediateOutputStream()->Flush(); result.GetImmediateErrorStream()->Flush(); @@ -2914,17 +2926,11 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { if (state == eStateStopped) { if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) { if (synchronous_execution) { - error = m_process_sp->PrivateResume(); - if (error.Success()) { - state = m_process_sp->WaitForProcessToStop( - llvm::None, nullptr, true, hijack_listener_sp, stream); - const bool must_be_alive = - false; // eStateExited is ok, so this must be false - if (!StateIsStoppedState(state, must_be_alive)) { - error.SetErrorStringWithFormat("process isn't stopped: %s", - StateAsCString(state)); - } - } + // Now we have handled the stop-from-attach, and we are just switching + // to a synchronous resume. So we should switch to the SyncResume + // hijacker. + m_process_sp->RestoreProcessEvents(); + m_process_sp->ResumeSynchronous(stream); } else { m_process_sp->RestoreProcessEvents(); error = m_process_sp->PrivateResume(); @@ -3143,12 +3149,13 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) { //-------------------------------------------------------------- Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid) : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(), - m_thread_spec_up(), m_active(true) {} + m_thread_spec_up() {} Target::StopHook::StopHook(const StopHook &rhs) : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp), m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp), - m_thread_spec_up(), m_active(rhs.m_active) { + m_thread_spec_up(), m_active(rhs.m_active), + m_auto_continue(rhs.m_auto_continue) { if (rhs.m_thread_spec_up) m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up)); } @@ -3175,6 +3182,9 @@ void Target::StopHook::GetDescription(Stream *s, else s->Indent("State: disabled\n"); + if (m_auto_continue) + s->Indent("AutoContinue on\n"); + if (m_specifier_sp) { s->Indent(); s->PutCString("Specifier:\n"); |