From cd16df9154d46bb4ff49ed8843df714a7376d072 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 20 Jul 2012 21:37:13 +0000 Subject: [PATCH] Add "vAttachOrWait" to debugserver, so you can implement "attach to the process if it exists OR wait for it" without race conditions. Use that in lldb. llvm-svn: 160578 --- lldb/include/lldb/API/SBTarget.h | 6 ++ lldb/include/lldb/Target/Process.h | 17 ++++ lldb/scripts/Python/interface/SBTarget.i | 6 ++ lldb/source/API/SBTarget.cpp | 12 +++ lldb/source/Commands/CommandObjectProcess.cpp | 15 ++-- .../GDBRemoteCommunicationClient.cpp | 21 +++++ .../gdb-remote/GDBRemoteCommunicationClient.h | 6 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 15 +++- lldb/source/Target/Process.cpp | 69 --------------- lldb/tools/debugserver/source/DNB.cpp | 9 +- lldb/tools/debugserver/source/DNB.h | 2 +- lldb/tools/debugserver/source/RNBRemote.cpp | 86 ++++++++++++------- lldb/tools/debugserver/source/RNBRemote.h | 3 + lldb/tools/debugserver/source/debugserver.cpp | 6 +- 14 files changed, 159 insertions(+), 114 deletions(-) diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 03636e3a2313..5dd93935aace 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -152,6 +152,12 @@ public: void SetWaitForLaunch (bool b); + bool + GetIgnoreExisting (); + + void + SetIgnoreExisting (bool b); + uint32_t GetResumeCount (); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index c876d75248d4..265303ebeab5 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -836,6 +836,7 @@ public: m_plugin_name (), m_resume_count (0), m_wait_for_launch (false), + m_ignore_existing (true), m_continue_once_attached (false) { } @@ -845,6 +846,7 @@ public: m_plugin_name (), m_resume_count (0), m_wait_for_launch (false), + m_ignore_existing (true), m_continue_once_attached (false) { ProcessInfo::operator= (launch_info); @@ -864,6 +866,18 @@ public: m_wait_for_launch = b; } + bool + GetIgnoreExisting () const + { + return m_ignore_existing; + } + + void + SetIgnoreExisting (bool b) + { + m_ignore_existing = b; + } + bool GetContinueOnceAttached () const { @@ -912,6 +926,8 @@ public: m_plugin_name.clear(); m_resume_count = 0; m_wait_for_launch = false; + m_ignore_existing = true; + m_continue_once_attached = false; } bool @@ -929,6 +945,7 @@ protected: std::string m_plugin_name; uint32_t m_resume_count; // How many times do we resume after launching bool m_wait_for_launch; + bool m_ignore_existing; bool m_continue_once_attached; // Supports the use-case scenario of immediately continuing the process once attached. }; diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i index a1eaeb010bea..8a304ee99c41 100644 --- a/lldb/scripts/Python/interface/SBTarget.i +++ b/lldb/scripts/Python/interface/SBTarget.i @@ -125,6 +125,12 @@ public: void SetWaitForLaunch (bool b); + bool + GetIgnoreExisting (); + + void + SetIgnoreExisting (bool b); + uint32_t GetResumeCount (); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 1dc30d1debca..7635a364901f 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -369,6 +369,18 @@ SBAttachInfo::SetWaitForLaunch (bool b) m_opaque_sp->SetWaitForLaunch (b); } +bool +SBAttachInfo::GetIgnoreExisting () +{ + return m_opaque_sp->GetIgnoreExisting(); +} + +void +SBAttachInfo::SetIgnoreExisting (bool b) +{ + m_opaque_sp->SetIgnoreExisting (b); +} + uint32_t SBAttachInfo::GetUserID() { diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 54f2a54beba3..f45e926adc63 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -350,6 +350,10 @@ public: case 'w': attach_info.SetWaitForLaunch(true); break; + + case 'i': + attach_info.SetIgnoreExisting(false); + break; default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); @@ -618,11 +622,12 @@ protected: OptionDefinition CommandObjectProcessAttach::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "continue",'c', no_argument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, -{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, -{ LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, -{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, -{ LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the process with to launch."}, +{ LLDB_OPT_SET_ALL, false, "continue",'c', no_argument, NULL, 0, eArgTypeNone, "Immediately continue the process once attached."}, +{ LLDB_OPT_SET_ALL, false, "plugin", 'P', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, +{ LLDB_OPT_SET_1, false, "pid", 'p', required_argument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."}, +{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."}, +{ LLDB_OPT_SET_2, false, "include-existing", 'i', no_argument, NULL, 0, eArgTypeNone, "Include existing processes when doing attach -w."}, +{ LLDB_OPT_SET_2, false, "waitfor", 'w', no_argument, NULL, 0, eArgTypeNone, "Wait for the process with to launch."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 180c1f3a5ef1..b4263d18ca63 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -50,6 +50,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : m_supports_memory_region_info (eLazyBoolCalculate), m_supports_watchpoint_support_info (eLazyBoolCalculate), m_watchpoints_trigger_after_instruction(eLazyBoolCalculate), + m_attach_or_wait_reply(eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -133,6 +134,26 @@ GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported () } } +bool +GDBRemoteCommunicationClient::GetVAttachOrWaitSupported () +{ + if (m_attach_or_wait_reply == eLazyBoolCalculate) + { + m_attach_or_wait_reply = eLazyBoolNo; + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false)) + { + if (response.IsOKResponse()) + m_attach_or_wait_reply = eLazyBoolYes; + } + } + if (m_attach_or_wait_reply == eLazyBoolYes) + return true; + else + return false; +} + void GDBRemoteCommunicationClient::ResetDiscoverableSettings() diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index a283389d2209..eee3aa50ed1d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -221,6 +221,9 @@ public: bool GetVContSupported (char flavor); + bool + GetVAttachOrWaitSupported (); + void ResetDiscoverableSettings(); @@ -365,7 +368,8 @@ protected: lldb_private::LazyBool m_supports_memory_region_info; lldb_private::LazyBool m_supports_watchpoint_support_info; lldb_private::LazyBool m_watchpoints_trigger_after_instruction; - + lldb_private::LazyBool m_attach_or_wait_reply; + bool m_supports_qProcessInfoPID:1, m_supports_qfProcessInfo:1, diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 6e48482901bd..dbb121e8a140 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -742,6 +742,7 @@ ProcessGDBRemote::ConnectToDebugserver (const char *connect_url) m_gdb_comm.GetListThreadsInStopReplySupported (); m_gdb_comm.GetHostInfo (); m_gdb_comm.GetVContSupported ('c'); + m_gdb_comm.GetVAttachOrWaitSupported(); size_t num_cmds = GetExtraStartupCommands().GetArgumentCount(); for (size_t idx = 0; idx < num_cmds; idx++) @@ -929,7 +930,19 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait StreamString packet; if (wait_for_launch) - packet.PutCString("vAttachWait"); + { + if (!m_gdb_comm.GetVAttachOrWaitSupported()) + { + packet.PutCString ("vAttachWait"); + } + else + { + if (attach_info.GetIgnoreExisting()) + packet.PutCString("vAttachWait"); + else + packet.PutCString ("vAttachOrWait"); + } + } else packet.PutCString("vAttachName"); packet.PutChar(';'); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 4b55e2738e3c..062b061c3919 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2709,75 +2709,6 @@ Process::Attach (ProcessAttachInfo &attach_info) return error; } -//Error -//Process::Attach (const char *process_name, bool wait_for_launch) -//{ -// m_abi_sp.reset(); -// m_process_input_reader.reset(); -// -// // Find the process and its architecture. Make sure it matches the architecture -// // of the current Target, and if not adjust it. -// Error error; -// -// if (!wait_for_launch) -// { -// ProcessInstanceInfoList process_infos; -// PlatformSP platform_sp (m_target.GetPlatform ()); -// assert (platform_sp.get()); -// -// if (platform_sp) -// { -// ProcessInstanceInfoMatch match_info; -// match_info.GetProcessInfo().SetName(process_name); -// match_info.SetNameMatchType (eNameMatchEquals); -// platform_sp->FindProcesses (match_info, process_infos); -// if (process_infos.GetSize() > 1) -// { -// error.SetErrorStringWithFormat ("more than one process named %s", process_name); -// } -// else if (process_infos.GetSize() == 0) -// { -// error.SetErrorStringWithFormat ("could not find a process named %s", process_name); -// } -// } -// else -// { -// error.SetErrorString ("invalid platform"); -// } -// } -// -// if (error.Success()) -// { -// m_dyld_ap.reset(); -// m_os_ap.reset(); -// -// error = WillAttachToProcessWithName(process_name, wait_for_launch); -// if (error.Success()) -// { -// SetPublicState (eStateAttaching); -// error = DoAttachToProcessWithName (process_name, wait_for_launch); -// if (error.Fail()) -// { -// if (GetID() != LLDB_INVALID_PROCESS_ID) -// { -// SetID (LLDB_INVALID_PROCESS_ID); -// const char *error_string = error.AsCString(); -// if (error_string == NULL) -// error_string = "attach failed"; -// -// SetExitStatus(-1, error_string); -// } -// } -// else -// { -// SetNextEventAction(new Process::AttachCompletionHandler(this, 0)); -// StartPrivateStateThread(); -// } -// } -// } -// return error; -//} - void Process::CompleteAttach () { diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index 0a29eaa8202c..6de893d0396e 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -499,7 +499,6 @@ GetAllInfosMatchingName(const char *full_process_name, std::vectorHandleReceivedPacket (&type); // check if we tried to attach to a process - if (type == RNBRemote::vattach || type == RNBRemote::vattachwait) + if (type == RNBRemote::vattach || type == RNBRemote::vattachwait || type == RNBRemote::vattachorwait) { if (err == rnb_success) return eRNBRunLoopModeInferiorExecuting; @@ -1319,8 +1319,8 @@ main (int argc, char *argv[]) } ctx.SetLaunchFlavor(launch_flavor); - - nub_process_t pid = DNBProcessAttachWait (waitfor_pid_name.c_str(), launch_flavor, timeout_ptr, waitfor_interval, err_str, sizeof(err_str)); + bool ignore_existing = false; + nub_process_t pid = DNBProcessAttachWait (waitfor_pid_name.c_str(), launch_flavor, ignore_existing, timeout_ptr, waitfor_interval, err_str, sizeof(err_str)); g_pid = pid; if (pid == INVALID_NUB_PROCESS)