summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ArchSpec.h23
-rw-r--r--lldb/include/lldb/Target/Process.h10
-rw-r--r--lldb/include/lldb/lldb-enumerations.h23
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp179
-rw-r--r--lldb/source/Core/ArchSpec.cpp28
-rw-r--r--lldb/source/Core/State.cpp3
-rw-r--r--lldb/source/Host/common/Host.cpp2
-rw-r--r--lldb/source/Interpreter/CommandObject.cpp69
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp1
-rw-r--r--lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp2
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp107
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h3
-rw-r--r--lldb/source/Target/Process.cpp44
-rw-r--r--lldb/tools/driver/Driver.cpp1
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:
OpenPOWER on IntegriCloud