diff options
Diffstat (limited to 'lldb/source/Plugins/Platform')
6 files changed, 267 insertions, 26 deletions
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 63cb4ac25ee..d3a11e43e84 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Error.h" #include "lldb/Host/Host.h" #include "lldb/Target/Target.h" @@ -50,17 +51,47 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file, Error error; // Nothing special to do here, just use the actual file and architecture + char exe_path[PATH_MAX]; FileSpec resolved_exe_file (exe_file); - // If we have "ls" as the exe_file, resolve the executable loation based on - // the current path variables - if (!resolved_exe_file.Exists()) - resolved_exe_file.ResolveExecutableLocation (); + if (IsHost()) + { + // If we have "ls" as the exe_file, resolve the executable loation based on + // the current path variables + if (!resolved_exe_file.Exists()) + { + exe_file.GetPath (exe_path, sizeof(exe_path)); + resolved_exe_file.SetFile(exe_path, true); + } - // Resolve any executable within a bundle on MacOSX - Host::ResolveExecutableInBundle (resolved_exe_file); + if (!resolved_exe_file.Exists()) + resolved_exe_file.ResolveExecutableLocation (); - if (resolved_exe_file.Exists()) + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle (resolved_exe_file); + + if (resolved_exe_file.Exists()) + error.Clear(); + else + { + exe_file.GetPath (exe_path, sizeof(exe_path)); + error.SetErrorStringWithFormat ("enable to find executable for '%s'", exe_path); + } + } + else + { + if (m_remote_platform_sp) + { + error = m_remote_platform_sp->ResolveExecutable (exe_file, + exe_arch, + exe_module_sp); + } + else + error.SetErrorString ("the platform is not currently connected"); + } + + + if (error.Success()) { if (exe_arch.IsValid()) { @@ -321,7 +352,7 @@ PlatformDarwin::DisconnectRemote () bool -PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) +PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { bool sucess = false; if (IsHost()) @@ -339,8 +370,8 @@ PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) uint32_t -PlatformDarwin::FindProcesses (const ProcessInfoMatch &match_info, - ProcessInfoList &process_infos) +PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { uint32_t match_count = 0; if (IsHost()) @@ -357,6 +388,71 @@ PlatformDarwin::FindProcesses (const ProcessInfoMatch &match_info, return match_count; } +Error +PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info) +{ + Error error; + if (IsHost()) + { + error = Platform::LaunchProcess (launch_info); + } + else + { + if (m_remote_platform_sp) + error = m_remote_platform_sp->LaunchProcess (launch_info); + else + error.SetErrorString ("the platform is not currently connected"); + } + return error; +} + +lldb::ProcessSP +PlatformDarwin::Attach (lldb::pid_t pid, + Debugger &debugger, + Target *target, + Listener &listener, + Error &error) +{ + lldb::ProcessSP process_sp; + if (IsHost()) + { + if (target == NULL) + { + TargetSP new_target_sp; + FileSpec emptyFileSpec; + ArchSpec emptyArchSpec; + + error = debugger.GetTargetList().CreateTarget (debugger, + emptyFileSpec, + emptyArchSpec, + false, + new_target_sp); + target = new_target_sp.get(); + } + else + error.Clear(); + + if (target && error.Success()) + { + debugger.GetTargetList().SetSelectedTarget(target); + // The darwin always currently uses the GDB remote debugger plug-in + // so even when debugging locally we are debugging remotely! + process_sp = target->CreateProcess (listener, "gdb-remote"); + + if (process_sp) + error = process_sp->Attach (pid); + } + } + else + { + if (m_remote_platform_sp) + process_sp = m_remote_platform_sp->Attach (pid, debugger, target, listener, error); + else + error.SetErrorString ("the platform is not currently connected"); + } + return process_sp; +} + const char * PlatformDarwin::GetUserName (uint32_t uid) { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index 74647360694..38804edad18 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -69,12 +69,22 @@ public: virtual bool GetProcessInfo (lldb::pid_t pid, - lldb_private::ProcessInfo &proc_info); + lldb_private::ProcessInstanceInfo &proc_info); virtual uint32_t - FindProcesses (const lldb_private::ProcessInfoMatch &match_info, - lldb_private::ProcessInfoList &process_infos); + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info, + lldb_private::ProcessInstanceInfoList &process_infos); + virtual lldb_private::Error + LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); + + virtual lldb::ProcessSP + Attach (lldb::pid_t pid, + lldb_private::Debugger &debugger, + lldb_private::Target *target, // Can be NULL, if NULL create a new target, else use existing one + lldb_private::Listener &listener, + lldb_private::Error &error); + protected: lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote darwin OS diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp index 2ae4a903353..3e0b2b14906 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp @@ -447,8 +447,8 @@ PlatformRemoteiOS::GetSharedModule (const FileSpec &platform_file, uint32_t -PlatformRemoteiOS::FindProcesses (const ProcessInfoMatch &match_info, - ProcessInfoList &process_infos) +PlatformRemoteiOS::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { // TODO: if connected, send a packet to get the remote process infos by name process_infos.Clear(); @@ -456,7 +456,7 @@ PlatformRemoteiOS::FindProcesses (const ProcessInfoMatch &match_info, } bool -PlatformRemoteiOS::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) +PlatformRemoteiOS::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { // TODO: if connected, send a packet to get the remote process info process_info.Clear(); diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h index 63ac8520de4..08968f4f110 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h @@ -103,12 +103,12 @@ public: bool *did_create_ptr); virtual uint32_t - FindProcesses (const lldb_private::ProcessInfoMatch &match_info, - lldb_private::ProcessInfoList &process_infos); + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info, + lldb_private::ProcessInstanceInfoList &process_infos); virtual bool GetProcessInfo (lldb::pid_t pid, - lldb_private::ProcessInfo &proc_info); + lldb_private::ProcessInstanceInfo &proc_info); virtual bool GetSupportedArchitectureAtIndex (uint32_t idx, diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index a6bcb9bf07e..f8b67a31280 100644 --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -17,6 +17,7 @@ // Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/ConnectionFileDescriptor.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Error.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" @@ -112,7 +113,8 @@ PlatformRemoteGDBServer::GetFile (const FileSpec &platform_file, /// Default Constructor //------------------------------------------------------------------ PlatformRemoteGDBServer::PlatformRemoteGDBServer () : - Platform(false) // This is a remote platform + Platform(false), // This is a remote platform + m_gdb_client(true) { } @@ -267,17 +269,139 @@ PlatformRemoteGDBServer::GetGroupName (uint32_t gid) } uint32_t -PlatformRemoteGDBServer::FindProcesses (const ProcessInfoMatch &match_info, - ProcessInfoList &process_infos) +PlatformRemoteGDBServer::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { return m_gdb_client.FindProcesses (match_info, process_infos); } bool -PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInfo &process_info) +PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { return m_gdb_client.GetProcessInfo (pid, process_info); } +Error +PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) +{ + Error error; + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + + m_gdb_client.SetSTDIN ("/dev/null"); + m_gdb_client.SetSTDOUT ("/dev/null"); + m_gdb_client.SetSTDERR ("/dev/null"); + m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)); + + const char *working_dir = launch_info.GetWorkingDirectory(); + if (working_dir && working_dir[0]) + { + m_gdb_client.SetWorkingDir (working_dir); + } + + // Send the environment and the program + arguments after we connect + const char **argv = launch_info.GetArguments().GetConstArgumentVector(); + const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector(); + + if (envp) + { + const char *env_entry; + for (int i=0; (env_entry = envp[i]); ++i) + { + if (m_gdb_client.SendEnvironmentPacket(env_entry) != 0) + break; + } + } + const uint32_t old_packet_timeout = m_gdb_client.SetPacketTimeout (3000); // TODO: lower this to 5 seconds prior to checkin!!! + int arg_packet_err = m_gdb_client.SendArgumentsPacket (argv); + m_gdb_client.SetPacketTimeout (old_packet_timeout); + if (arg_packet_err == 0) + { + std::string error_str; + if (m_gdb_client.GetLaunchSuccess (error_str)) + { + pid = m_gdb_client.GetCurrentProcessID (); + if (pid != LLDB_INVALID_PROCESS_ID) + launch_info.SetProcessID (pid); + } + else + { + error.SetErrorString (error_str.c_str()); + } + } + else + { + error.SetErrorStringWithFormat("'A' packet returned an error: %i.\n", arg_packet_err); + } + return error; +} + +lldb::ProcessSP +PlatformRemoteGDBServer::Attach (lldb::pid_t pid, + Debugger &debugger, + Target *target, // Can be NULL, if NULL create a new target, else use existing one + Listener &listener, + Error &error) +{ + lldb::ProcessSP process_sp; + if (IsRemote()) + { + if (IsConnected()) + { + uint16_t port = m_gdb_client.LaunchGDBserverAndGetPort(); + + if (port == 0) + { + error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ()); + } + else + { + if (target == NULL) + { + TargetSP new_target_sp; + FileSpec emptyFileSpec; + ArchSpec emptyArchSpec; + + error = debugger.GetTargetList().CreateTarget (debugger, + emptyFileSpec, + emptyArchSpec, + false, + new_target_sp); + target = new_target_sp.get(); + } + else + error.Clear(); + + if (target && error.Success()) + { + debugger.GetTargetList().SetSelectedTarget(target); + + // The darwin always currently uses the GDB remote debugger plug-in + // so even when debugging locally we are debugging remotely! + process_sp = target->CreateProcess (listener, "gdb-remote"); + + if (process_sp) + { + char connect_url[256]; + const int connect_url_len = ::snprintf (connect_url, + sizeof(connect_url), + "connect://%s:%u", + GetHostname (), + port); + assert (connect_url_len < sizeof(connect_url)); + error = process_sp->ConnectRemote (connect_url); + if (error.Success()) + error = process_sp->Attach(pid); + } + } + } + } + else + { + error.SetErrorString("not connected to remote gdb server"); + } + } + return process_sp; +} + diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index a016e01d008..36c48c24b60 100644 --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -83,11 +83,22 @@ public: lldb_private::FileSpec &local_file); virtual bool - GetProcessInfo (lldb::pid_t pid, lldb_private::ProcessInfo &proc_info); + GetProcessInfo (lldb::pid_t pid, + lldb_private::ProcessInstanceInfo &proc_info); virtual uint32_t - FindProcesses (const lldb_private::ProcessInfoMatch &match_info, - lldb_private::ProcessInfoList &process_infos); + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info, + lldb_private::ProcessInstanceInfoList &process_infos); + + virtual lldb_private::Error + LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); + + virtual lldb::ProcessSP + Attach (lldb::pid_t pid, + lldb_private::Debugger &debugger, + lldb_private::Target *target, // Can be NULL, if NULL create a new target, else use existing one + lldb_private::Listener &listener, + lldb_private::Error &error); virtual bool GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch); |

