diff options
-rw-r--r-- | lldb/include/lldb/Core/ArchSpec.h | 23 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 10 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 23 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectProcess.cpp | 179 | ||||
-rw-r--r-- | lldb/source/Core/ArchSpec.cpp | 28 | ||||
-rw-r--r-- | lldb/source/Core/State.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Host/common/Host.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandObject.cpp | 69 | ||||
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 107 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 3 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 44 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 1 |
15 files changed, 391 insertions, 114 deletions
diff --git a/lldb/include/lldb/Core/ArchSpec.h b/lldb/include/lldb/Core/ArchSpec.h index c95b824f2f3..38353fcad14 100644 --- a/lldb/include/lldb/Core/ArchSpec.h +++ b/lldb/include/lldb/Core/ArchSpec.h @@ -262,23 +262,12 @@ public: /// @param[in] subtype The new CPU subtype //------------------------------------------------------------------ void - SetArch (uint32_t cpu, uint32_t subtype); - - //------------------------------------------------------------------ - /// Change the CPU subtype given a new value of the CPU subtype. - /// - /// @param[in] subtype The new CPU subtype. - //------------------------------------------------------------------ - void - SetCPUSubtype (uint32_t subtype); - - //------------------------------------------------------------------ - /// Change the CPU type given a new value of the CPU type. - /// - /// @param[in] cpu The new CPU type. - //------------------------------------------------------------------ - void - SetCPUType (uint32_t cpu); + SetMachOArch (uint32_t cpu, uint32_t sub) + { + m_type = lldb::eArchTypeMachO; + m_cpu = cpu; + m_sub = sub; + } //------------------------------------------------------------------ /// Returns the default endianness of the architecture. diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index fcf48afef37..009d265f75c 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -595,6 +595,8 @@ public: virtual Error Attach (const char *process_name, bool wait_for_launch); + virtual Error + ConnectRemote (const char *remote_url); //------------------------------------------------------------------ /// List the processes matching the given partial name. /// @@ -856,6 +858,14 @@ public: return Error(); } + virtual Error + DoConnectRemote (const char *remote_url) + { + Error error; + error.SetErrorString ("remote connections are not supported"); + return error; + } + //------------------------------------------------------------------ /// Attach to an existing process using a process ID. /// diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 5748fe3638b..0a58052eea7 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -18,16 +18,19 @@ namespace lldb { typedef enum StateType { eStateInvalid = 0, - eStateUnloaded, - eStateAttaching, - eStateLaunching, - eStateStopped, - eStateRunning, - eStateStepping, - eStateCrashed, - eStateDetached, - eStateExited, - eStateSuspended + eStateUnloaded, ///< Process is object is valid, but not currently loaded + eStateConnected, ///< Process is connected to remote debug services, but not launched or attached to anything yet + eStateAttaching, ///< Process is currently trying to attach + eStateLaunching, ///< Process is in the process of launching + eStateStopped, ///< Process or thread is stopped and can be examined. + eStateRunning, ///< Process or thread is running and can't be examined. + eStateStepping, ///< Process or thread is in the process of stepping and can not be examined. + eStateCrashed, ///< Process or thread has crashed and can be examined. + eStateDetached, ///< Process has been detached and can't be examined. + eStateExited, ///< Process has exited and can't be examined. + eStateSuspended ///< Process or thread is in a suspended state as far + ///< as the debugger is concerned while other processes + ///< or threads get the chance to run. } StateType; //---------------------------------------------------------------------- diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 7dd42237ea7..181012d12f0 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -572,7 +572,7 @@ public: target = new_target_sp.get(); if (target == NULL || error.Fail()) { - result.AppendError(error.AsCString("Error creating empty target")); + result.AppendError(error.AsCString("Error creating target")); return false; } m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target); @@ -930,6 +930,182 @@ public: }; //------------------------------------------------------------------------- +// CommandObjectProcessConnect +//------------------------------------------------------------------------- +#pragma mark CommandObjectProcessConnect + +class CommandObjectProcessConnect : public CommandObject +{ +public: + + class CommandOptions : public Options + { + public: + + CommandOptions () : + Options() + { + // Keep default values of all options in one place: ResetOptionValues () + ResetOptionValues (); + } + + ~CommandOptions () + { + } + + Error + SetOptionValue (int option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'p': + plugin_name.assign (option_arg); + break; + + default: + error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); + break; + } + return error; + } + + void + ResetOptionValues () + { + Options::ResetOptionValues(); + plugin_name.clear(); + } + + const lldb::OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static lldb::OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + std::string plugin_name; + }; + + CommandObjectProcessConnect (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "process connect", + "Connect to a remote debug service.", + "process connect <remote-url>", + 0) + { + } + + ~CommandObjectProcessConnect () + { + } + + + bool + Execute (Args& command, + CommandReturnObject &result) + { + + TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget()); + Error error; + Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; + if (process) + { + if (process->IsAlive()) + { + result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before connecting.\n", + process->GetID()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + + if (!target_sp) + { + // If there isn't a current target create one. + FileSpec emptyFileSpec; + ArchSpec emptyArchSpec; + + error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(), + emptyFileSpec, + emptyArchSpec, + NULL, + false, + target_sp); + if (!target_sp || error.Fail()) + { + result.AppendError(error.AsCString("Error creating target")); + result.SetStatus (eReturnStatusFailed); + return false; + } + m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target_sp.get()); + } + + if (command.GetArgumentCount() == 1) + { + const char *plugin_name = NULL; + if (!m_options.plugin_name.empty()) + plugin_name = m_options.plugin_name.c_str(); + + const char *remote_url = command.GetArgumentAtIndex(0); + process = target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get(); + + if (process) + { + error = process->ConnectRemote (remote_url); + + if (error.Fail()) + { + result.AppendError(error.AsCString("Remote connect failed")); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + result.AppendErrorWithFormat ("Unable to find process plug-in for remote URL '%s'.\nPlease specify a process plug-in name with the --plugin option, or specify an object file using the \"file\" command: \n", + m_cmd_name.c_str(), + m_cmd_syntax.c_str()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: \n", + m_cmd_name.c_str(), + m_cmd_syntax.c_str()); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } + + Options * + GetOptions () + { + return &m_options; + } + +protected: + + CommandOptions m_options; +}; + + +lldb::OptionDefinition +CommandObjectProcessConnect::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, + { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } +}; + +//------------------------------------------------------------------------- // CommandObjectProcessLoad //------------------------------------------------------------------------- #pragma mark CommandObjectProcessLoad @@ -1656,6 +1832,7 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter))); LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter))); LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter))); + LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter))); LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter))); LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter))); LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter))); diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index 5c8a3c1dc4b..caecf02b7e4 100644 --- a/lldb/source/Core/ArchSpec.cpp +++ b/lldb/source/Core/ArchSpec.cpp @@ -1776,34 +1776,6 @@ ArchSpec::SetArch (const char *arch_name) return false; } -//---------------------------------------------------------------------- -// CPU type and subtype set accessor. -//---------------------------------------------------------------------- -void -ArchSpec::SetArch (uint32_t cpu_type, uint32_t cpu_subtype) -{ - m_cpu = cpu_type; - m_sub = cpu_subtype; -} - -//---------------------------------------------------------------------- -// CPU type set accessor. -//---------------------------------------------------------------------- -void -ArchSpec::SetCPUType (uint32_t cpu) -{ - m_cpu = cpu; -} - -//---------------------------------------------------------------------- -// CPU subtype set accessor. -//---------------------------------------------------------------------- -void -ArchSpec::SetCPUSubtype (uint32_t subtype) -{ - m_sub = subtype; -} - ByteOrder ArchSpec::GetDefaultEndian () const { diff --git a/lldb/source/Core/State.cpp b/lldb/source/Core/State.cpp index a68ac73092a..bf0ef3367a6 100644 --- a/lldb/source/Core/State.cpp +++ b/lldb/source/Core/State.cpp @@ -24,6 +24,7 @@ lldb_private::StateAsCString (StateType state) { case eStateInvalid: return "invalid"; case eStateUnloaded: return "unloaded"; + case eStateConnected: return "connected"; case eStateAttaching: return "attaching"; case eStateLaunching: return "launching"; case eStateStopped: return "stopped"; @@ -50,6 +51,7 @@ lldb_private::StateIsRunningState (StateType state) case eStateStepping: return true; + case eStateConnected: case eStateDetached: case eStateInvalid: case eStateUnloaded: @@ -69,6 +71,7 @@ lldb_private::StateIsStoppedState (StateType state) switch (state) { case eStateInvalid: + case eStateConnected: case eStateAttaching: case eStateLaunching: case eStateRunning: diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 2f4247d4101..e453b2915d4 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -229,7 +229,7 @@ Host::GetArchitecture () { len = sizeof(cpusubtype); if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) - g_host_arch.SetArch(cputype, cpusubtype); + g_host_arch.SetMachOArch (cputype, cpusubtype); len = sizeof (is_64_bit_capable); if (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0) diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index df35ba98738..e53b111bdf1 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -217,48 +217,49 @@ CommandObject::ExecuteWithOptions (Args& args, CommandReturnObject &result) args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str)); } - Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; - if (process == NULL) + if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused)) { - if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused)) + Process *process = m_interpreter.GetDebugger().GetExecutionContext().process; + if (process == NULL) { result.AppendError ("Process must exist."); result.SetStatus (eReturnStatusFailed); return false; } - } - else - { - StateType state = process->GetState(); - - switch (state) + else { - - case eStateAttaching: - case eStateLaunching: - case eStateSuspended: - case eStateCrashed: - case eStateStopped: - break; - - case eStateDetached: - case eStateExited: - case eStateUnloaded: - if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched)) - { - result.AppendError ("Process must be launched."); - result.SetStatus (eReturnStatusFailed); - return false; - } - break; - - case eStateRunning: - case eStateStepping: - if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused)) + StateType state = process->GetState(); + + switch (state) { - result.AppendError ("Process is running. Use 'process interrupt' to pause execution."); - result.SetStatus (eReturnStatusFailed); - return false; + + case eStateSuspended: + case eStateCrashed: + case eStateStopped: + break; + + case eStateConnected: + case eStateAttaching: + case eStateLaunching: + case eStateDetached: + case eStateExited: + case eStateUnloaded: + if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched)) + { + result.AppendError ("Process must be launched."); + result.SetStatus (eReturnStatusFailed); + return false; + } + break; + + case eStateRunning: + case eStateStepping: + if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused)) + { + result.AppendError ("Process is running. Use 'process interrupt' to pause execution."); + result.SetStatus (eReturnStatusFailed); + return false; + } } } } diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 68aa0e00bd8..6c0c7b0cb56 100644 --- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -1106,6 +1106,7 @@ DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state)); switch (state) { + case eStateConnected: case eStateAttaching: case eStateLaunching: case eStateInvalid: diff --git a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp index 9312cce977d..c2f8edc415b 100644 --- a/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp +++ b/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp @@ -190,7 +190,7 @@ ObjectContainerUniversalMachO::GetArchitectureAtIndex (uint32_t idx, ArchSpec& a { if (idx < m_header.nfat_arch) { - arch.SetArch(m_fat_archs[idx].cputype, m_fat_archs[idx].cpusubtype); + arch.SetMachOArch (m_fat_archs[idx].cputype, m_fat_archs[idx].cpusubtype); return true; } return false; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 52b23762d76..769849d47b3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -836,17 +836,20 @@ GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds) std::string name; std::string value; + uint32_t cpu = LLDB_INVALID_CPUTYPE; + uint32_t sub = 0; + while (response.GetNameColonValue(name, value)) { if (name.compare("cputype") == 0) { // exception type in big endian hex - m_arch.SetCPUType(Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0)); + cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); } else if (name.compare("cpusubtype") == 0) { // exception count in big endian hex - m_arch.SetCPUSubtype(Args::StringToUInt32 (value.c_str(), 0, 0)); + sub = Args::StringToUInt32 (value.c_str(), 0, 0); } else if (name.compare("ostype") == 0) { @@ -871,6 +874,9 @@ GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds) m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); } } + + if (cpu != LLDB_INVALID_CPUTYPE) + m_arch.SetMachOArch (cpu, sub); } return HostInfoIsValid(); } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 2fd77223740..2da0de9ac76 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -354,6 +354,56 @@ ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wa } Error +ProcessGDBRemote::DoConnectRemote (const char *remote_url) +{ + Error error (WillLaunchOrAttach ()); + + if (error.Fail()) + return error; + + if (strncmp (remote_url, "connect://", strlen ("connect://")) == 0) + { + error = ConnectToDebugserver (remote_url); + } + else + { + error.SetErrorStringWithFormat ("unsupported remote url: %s", remote_url); + } + + if (error.Fail()) + return error; + StartAsyncThread (); + + lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (m_packet_timeout); + if (pid == LLDB_INVALID_PROCESS_ID) + { + // We don't have a valid process ID, so note that we are connected + // and could now request to launch or attach, or get remote process + // listings... + SetPrivateState (eStateConnected); + } + else + { + // We have a valid process + SetID (pid); + StringExtractorGDBRemote response; + if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, response, m_packet_timeout, false)) + { + const StateType state = SetThreadStopInfo (response); + if (state == eStateStopped) + { + SetPrivateState (state); + } + else + error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state)); + } + else + error.SetErrorStringWithFormat ("Process %i was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url); + } + return error; +} + +Error ProcessGDBRemote::WillLaunchOrAttach () { Error error; @@ -394,6 +444,8 @@ ProcessGDBRemote::DoLaunch ArchSpec inferior_arch(module->GetArchitecture()); char host_port[128]; snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); + char connect_url[128]; + snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); const bool launch_process = true; bool start_debugserver_with_inferior_args = false; @@ -417,7 +469,7 @@ ProcessGDBRemote::DoLaunch if (error.Fail()) return error; - error = ConnectToDebugserver (host_port); + error = ConnectToDebugserver (connect_url); if (error.Success()) { SetID (m_gdb_comm.GetCurrentProcessID (m_packet_timeout)); @@ -441,7 +493,7 @@ ProcessGDBRemote::DoLaunch if (error.Fail()) return error; - error = ConnectToDebugserver (host_port); + error = ConnectToDebugserver (connect_url); if (error.Success()) { // Send the environment and the program + arguments after we connect @@ -515,20 +567,18 @@ ProcessGDBRemote::DoLaunch Error -ProcessGDBRemote::ConnectToDebugserver (const char *host_port) +ProcessGDBRemote::ConnectToDebugserver (const char *connect_url) { Error error; // Sleep and wait a bit for debugserver to start to listen... std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); if (conn_ap.get()) { - std::string connect_url("connect://"); - connect_url.append (host_port); const uint32_t max_retry_count = 50; uint32_t retry_count = 0; while (!m_gdb_comm.IsConnected()) { - if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess) + if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess) { m_gdb_comm.SetConnection (conn_ap.release()); break; @@ -596,21 +646,31 @@ ProcessGDBRemote::DidLaunchOrAttach () StreamString strm; - ArchSpec inferior_arch; + ArchSpec inferior_arch (m_gdb_comm.GetHostArchitecture()); + // See if the GDB server supports the qHostInfo information const char *vendor = m_gdb_comm.GetVendorString().AsCString(); const char *os_type = m_gdb_comm.GetOSString().AsCString(); - ArchSpec arch_spec (GetTarget().GetArchitecture()); - - if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm")) + const ArchSpec target_arch (GetTarget().GetArchitecture()); + const ArchSpec arm_any("arm"); + bool set_target_arch = true; + if (target_arch.IsValid()) { - // For ARM we can't trust the arch of the process as it could - // have an armv6 object file, but be running on armv7 kernel. - inferior_arch = m_gdb_comm.GetHostArchitecture(); + if (inferior_arch == arm_any) + { + // For ARM we can't trust the arch of the process as it could + // have an armv6 object file, but be running on armv7 kernel. + // So we only set the ARM architecture if the target isn't set + // to ARM already... + if (target_arch == arm_any) + { + inferior_arch = target_arch; + set_target_arch = false; + } + } } - - if (!inferior_arch.IsValid()) - inferior_arch = arch_spec; + if (set_target_arch) + GetTarget().SetArchitecture (inferior_arch); if (vendor == NULL) vendor = Host::GetVendorString().AsCString("apple"); @@ -652,6 +712,9 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) { char host_port[128]; snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); + char connect_url[128]; + snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); + error = StartDebugserverProcess (host_port, // debugserver_url NULL, // inferior_argv NULL, // inferior_envp @@ -676,7 +739,7 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) } else { - error = ConnectToDebugserver (host_port); + error = ConnectToDebugserver (connect_url); if (error.Success()) { char packet[64]; @@ -722,9 +785,13 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait //LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); if (process_name && process_name[0]) { - char host_port[128]; ArchSpec arch_spec = GetTarget().GetArchitecture(); + + char host_port[128]; snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); + char connect_url[128]; + snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); + error = StartDebugserverProcess (host_port, // debugserver_url NULL, // inferior_argv NULL, // inferior_envp @@ -748,7 +815,7 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait } else { - error = ConnectToDebugserver (host_port); + error = ConnectToDebugserver (connect_url); if (error.Success()) { StreamString packet; @@ -772,9 +839,9 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait void ProcessGDBRemote::DidAttach () { + DidLaunchOrAttach (); if (m_dynamic_loader_ap.get()) m_dynamic_loader_ap->DidAttach(); - DidLaunchOrAttach (); } Error diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index af3084c6496..8db580b53f9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -95,6 +95,9 @@ public: virtual lldb_private::Error WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); + virtual lldb_private::Error + DoConnectRemote (const char *remote_url); + lldb_private::Error WillLaunchOrAttach (); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 658280c83e4..0df8077b75f 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1737,6 +1737,49 @@ Process::Attach (const char *process_name, bool wait_for_launch) } Error +Process::ConnectRemote (const char *remote_url) +{ + m_target_triple.Clear(); + 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 (DoConnectRemote (remote_url)); + if (error.Success()) + { + SetNextEventAction(new Process::AttachCompletionHandler(this)); + StartPrivateStateThread(); +// TimeValue timeout; +// timeout = TimeValue::Now(); +// timeout.OffsetWithMicroSeconds(000); +// EventSP event_sp; +// StateType state = WaitForProcessStopPrivate(NULL, event_sp); +// +// if (state == eStateStopped || state == eStateCrashed) +// { +// DidLaunch (); +// +// // This delays passing the stopped event to listeners till DidLaunch gets +// // a chance to complete... +// HandlePrivateEvent (event_sp); +// StartPrivateStateThread (); +// } +// else if (state == eStateExited) +// { +// // We exited while trying to launch somehow. Don't call DidLaunch as that's +// // not likely to work, and return an invalid pid. +// HandlePrivateEvent (event_sp); +// } +// +// StartPrivateStateThread(); + } + return error; +} + + +Error Process::Resume () { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); @@ -1948,6 +1991,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr) switch (state) { + case eStateConnected: case eStateAttaching: case eStateLaunching: case eStateDetached: diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index f44978efbc2..1cc3d1947ac 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -822,6 +822,7 @@ Driver::HandleProcessEvent (const SBEvent &event) { case eStateInvalid: case eStateUnloaded: + case eStateConnected: case eStateAttaching: case eStateLaunching: case eStateStepping: |