[Lldb-commits] [lldb] r124846 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Target/ source/Commands/ source/Core/ source/Host/common/ source/Interpreter/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/ObjectContainer/Universal-Mach-O/ source/Plugins/Process/gdb-remote/ source/Target/ tools/driver/
Greg Clayton
gclayton at apple.com
Thu Feb 3 17:58:07 PST 2011
Author: gclayton
Date: Thu Feb 3 19:58:07 2011
New Revision: 124846
URL: http://llvm.org/viewvc/llvm-project?rev=124846&view=rev
Log:
Added support for attaching to a remote debug server with the new command:
(lldb) process connect <remote-url>
Currently when you specify a file with the file command it helps us to find
a process plug-in that is suitable for debugging. If you specify a file you
can rely upon this to find the correct debugger plug-in:
% lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) process connect connect://localhost:2345
...
If you don't specify a file, you will need to specify the plug-in name that
you wish to use:
% lldb
(lldb) process connect --plugin process.gdb-remote connect://localhost:2345
Other connection URL examples:
(lldb) process connect connect://localhost:2345
(lldb) process connect tcp://127.0.0.1
(lldb) process connect file:///dev/ttyS1
We are currently treating the "connect://host:port" as a way to do raw socket
connections. If there is a URL for this already, please let me know and we
will adopt it.
So now you can connect to a remote debug server with the ProcessGDBRemote
plug-in. After connection, it will ask for the pid info using the "qC" packet
and if it responds with a valid process ID, it will be equivalent to attaching.
If it response with an error or invalid process ID, the LLDB process will be
in a new state: eStateConnected. This allows us to then download a program or
specify the program to run (using the 'A' packet), or specify a process to
attach to (using the "vAttach" packets), or query info about the processes
that might be available.
Modified:
lldb/trunk/include/lldb/Core/ArchSpec.h
lldb/trunk/include/lldb/Target/Process.h
lldb/trunk/include/lldb/lldb-enumerations.h
lldb/trunk/source/Commands/CommandObjectProcess.cpp
lldb/trunk/source/Core/ArchSpec.cpp
lldb/trunk/source/Core/State.cpp
lldb/trunk/source/Host/common/Host.cpp
lldb/trunk/source/Interpreter/CommandObject.cpp
lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/trunk/source/Target/Process.cpp
lldb/trunk/tools/driver/Driver.cpp
Modified: lldb/trunk/include/lldb/Core/ArchSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ArchSpec.h?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ArchSpec.h (original)
+++ lldb/trunk/include/lldb/Core/ArchSpec.h Thu Feb 3 19:58:07 2011
@@ -262,23 +262,12 @@
/// @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.
Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Thu Feb 3 19:58:07 2011
@@ -595,6 +595,8 @@
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 @@
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.
///
Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Thu Feb 3 19:58:07 2011
@@ -18,16 +18,19 @@
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;
//----------------------------------------------------------------------
Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Thu Feb 3 19:58:07 2011
@@ -572,7 +572,7 @@
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 @@
};
//-------------------------------------------------------------------------
+// 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 @@
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)));
Modified: lldb/trunk/source/Core/ArchSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ArchSpec.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Core/ArchSpec.cpp (original)
+++ lldb/trunk/source/Core/ArchSpec.cpp Thu Feb 3 19:58:07 2011
@@ -1776,34 +1776,6 @@
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
{
Modified: lldb/trunk/source/Core/State.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/State.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Core/State.cpp (original)
+++ lldb/trunk/source/Core/State.cpp Thu Feb 3 19:58:07 2011
@@ -24,6 +24,7 @@
{
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 @@
case eStateStepping:
return true;
+ case eStateConnected:
case eStateDetached:
case eStateInvalid:
case eStateUnloaded:
@@ -69,6 +71,7 @@
switch (state)
{
case eStateInvalid:
+ case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateRunning:
Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Thu Feb 3 19:58:07 2011
@@ -229,7 +229,7 @@
{
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)
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Thu Feb 3 19:58:07 2011
@@ -217,48 +217,49 @@
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;
+ }
}
}
}
Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Thu Feb 3 19:58:07 2011
@@ -1106,6 +1106,7 @@
DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
switch (state)
{
+ case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateInvalid:
Modified: lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp Thu Feb 3 19:58:07 2011
@@ -190,7 +190,7 @@
{
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;
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Thu Feb 3 19:58:07 2011
@@ -836,17 +836,20 @@
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 @@
m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
}
}
+
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ m_arch.SetMachOArch (cpu, sub);
}
return HostInfoIsValid();
}
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Thu Feb 3 19:58:07 2011
@@ -354,6 +354,56 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
}
else
{
- error = ConnectToDebugserver (host_port);
+ error = ConnectToDebugserver (connect_url);
if (error.Success())
{
char packet[64];
@@ -722,9 +785,13 @@
//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 @@
}
else
{
- error = ConnectToDebugserver (host_port);
+ error = ConnectToDebugserver (connect_url);
if (error.Success())
{
StreamString packet;
@@ -772,9 +839,9 @@
void
ProcessGDBRemote::DidAttach ()
{
+ DidLaunchOrAttach ();
if (m_dynamic_loader_ap.get())
m_dynamic_loader_ap->DidAttach();
- DidLaunchOrAttach ();
}
Error
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Thu Feb 3 19:58:07 2011
@@ -95,6 +95,9 @@
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 ();
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Thu Feb 3 19:58:07 2011
@@ -1737,6 +1737,49 @@
}
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 @@
switch (state)
{
+ case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateDetached:
Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=124846&r1=124845&r2=124846&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Thu Feb 3 19:58:07 2011
@@ -822,6 +822,7 @@
{
case eStateInvalid:
case eStateUnloaded:
+ case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateStepping:
More information about the lldb-commits
mailing list