diff options
author | Dave Lee <davelee.com@gmail.com> | 2023-06-27 14:12:45 -0700 |
---|---|---|
committer | Dave Lee <davelee.com@gmail.com> | 2023-06-27 15:29:52 -0700 |
commit | 86fd957af981f146a306831608d7ad2de65b9560 (patch) | |
tree | 12714d7e6dd33c603d816da367a2623df71631cb /lldb/source/Commands/CommandObjectPlatform.cpp | |
parent | ab674234c440ed27302f58eeccc612c83b32c43f (diff) | |
download | llvm-86fd957af981f146a306831608d7ad2de65b9560.zip llvm-86fd957af981f146a306831608d7ad2de65b9560.tar.gz llvm-86fd957af981f146a306831608d7ad2de65b9560.tar.bz2 |
[lldb] Duplicate Target::Launch resuming logic into CommandObjectPlatformProcessLaunch
Fix `platform process launch` on macOS where it fails for lack of auto-resuming support.
This change reproduces the resuming logic found in `Target::Launch`.
This issue was identified by @DavidSpickett in D153636. This change relies on the tests
added in that PR. Thanks David.
Differential Revision: https://reviews.llvm.org/D153922
Diffstat (limited to 'lldb/source/Commands/CommandObjectPlatform.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectPlatform.cpp | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index 92aa110..e44a897 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -25,6 +25,7 @@ #include "lldb/Target/Process.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/ScriptedMetadata.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/SmallString.h" @@ -1212,15 +1213,65 @@ protected: ProcessSP process_sp(platform_sp->DebugProcess( m_options.launch_info, debugger, *target, error)); + + if (!process_sp && error.Success()) { + result.AppendError("failed to launch or debug process"); + return false; + } else if (!error.Success()) { + result.AppendError(error.AsCString()); + return false; + } + + const bool synchronous_execution = + debugger.GetCommandInterpreter().GetSynchronous(); + auto launch_info = m_options.launch_info; + bool rebroadcast_first_stop = + !synchronous_execution && + launch_info.GetFlags().Test(eLaunchFlagStopAtEntry); + + assert(launch_info.GetHijackListener()); + + EventSP first_stop_event_sp; + StateType state = process_sp->WaitForProcessToStop( + std::nullopt, &first_stop_event_sp, rebroadcast_first_stop, + launch_info.GetHijackListener()); + process_sp->RestoreProcessEvents(); + + if (rebroadcast_first_stop) { + assert(first_stop_event_sp); + process_sp->BroadcastEvent(first_stop_event_sp); + return true; + } + + switch (state) { + case eStateStopped: { + if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) + break; + if (synchronous_execution) { + // 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. + process_sp->ResumeSynchronous(&result.GetOutputStream()); + } else { + error = process_sp->Resume(); + if (!error.Success()) { + result.AppendErrorWithFormat( + "process resume at entry point failed: %s", + error.AsCString()); + } + } + } break; + default: + result.AppendErrorWithFormat( + "initial process state wasn't stopped: %s", + StateAsCString(state)); + break; + } + if (process_sp && process_sp->IsAlive()) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; } - - if (error.Success()) - result.AppendError("process launch failed"); - else - result.AppendError(error.AsCString()); } else { result.AppendError("'platform process launch' uses the current target " "file and arguments, or the executable and its " |