diff options
| author | Greg Clayton <gclayton@apple.com> | 2011-11-29 20:50:10 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2011-11-29 20:50:10 +0000 |
| commit | 28041352cb05b0da78da40667dbc6c9f1819f36a (patch) | |
| tree | c97b89324fc7c96550d0ae0a5238ae4c33007eea /lldb/source | |
| parent | 31798ef3c0bb04791ad0e68b60bdb89ec8599379 (diff) | |
| download | bcm5719-llvm-28041352cb05b0da78da40667dbc6c9f1819f36a.tar.gz bcm5719-llvm-28041352cb05b0da78da40667dbc6c9f1819f36a.zip | |
Patch from Dawn that fixes up linux debugging and a first passs at an
implementation of the linux platform.
llvm-svn: 145433
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp | 205 | ||||
| -rw-r--r-- | lldb/source/Plugins/Platform/Linux/PlatformLinux.h | 14 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/ProcessLinux.cpp | 12 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp | 40 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/ProcessMonitor.h | 12 |
5 files changed, 221 insertions, 62 deletions
diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index a9e390c99d0..2eb333b88e4 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -17,6 +17,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Error.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" @@ -29,10 +30,12 @@ using namespace lldb; using namespace lldb_private; +static uint32_t g_initialize_count = 0; + Platform * PlatformLinux::CreateInstance () { - return new PlatformLinux(); + return new PlatformLinux(true); } const char * @@ -42,33 +45,51 @@ PlatformLinux::GetPluginNameStatic() } const char * -PlatformLinux::GetPluginDescriptionStatic() +PlatformLinux::GetShortPluginNameStatic (bool is_host) +{ + if (is_host) + return Platform::GetHostPlatformName (); + else + return "remote-linux"; +} + +const char * +PlatformLinux::GetPluginDescriptionStatic (bool is_host) { - return "Default platform plugin for Linux"; + if (is_host) + return "Local Linux user platform plug-in."; + else + return "Remote Linux user platform plug-in."; } void PlatformLinux::Initialize () { - static bool g_initialized = false; - - if (!g_initialized) + if (g_initialize_count++ == 0) { - PlatformSP default_platform_sp (CreateInstance()); +#if defined(__linux__) + PlatformSP default_platform_sp (new PlatformLinux(true)); + default_platform_sp->SetSystemArchitecture (Host::GetArchitecture()); Platform::SetDefaultPlatform (default_platform_sp); - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - g_initialized = true; +#endif + PluginManager::RegisterPlugin(PlatformLinux::GetShortPluginNameStatic(false), + PlatformLinux::GetPluginDescriptionStatic(false), + PlatformLinux::CreateInstance); } } void PlatformLinux::Terminate () { + if (g_initialize_count > 0) + { + if (--g_initialize_count == 0) + { + PluginManager::UnregisterPlugin (PlatformLinux::CreateInstance); + } + } } - Error PlatformLinux::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, @@ -77,17 +98,50 @@ PlatformLinux::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 location 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()) + if (resolved_exe_file.Exists()) + error.Clear(); + else + { + exe_file.GetPath(exe_path, sizeof(exe_path)); + error.SetErrorStringWithFormat("unable 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 + { + // We may connect to a process and use the provided executable (Don't use local $PATH). + + if (resolved_exe_file.Exists()) + error.Clear(); + else + error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); + } + } + + if (error.Success()) { if (exe_arch.IsValid()) { @@ -152,21 +206,20 @@ PlatformLinux::ResolveExecutable (const FileSpec &exe_file, } } } - else - { - error.SetErrorStringWithFormat ("'%s%s%s' does not exist", - exe_file.GetDirectory().AsCString(""), - exe_file.GetDirectory() ? "/" : "", - exe_file.GetFilename().AsCString("")); - } return error; } Error PlatformLinux::GetFile (const FileSpec &platform_file, - const UUID *uuid, FileSpec &local_file) + const UUID *uuid_ptr, FileSpec &local_file) { + if (IsRemote()) + { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetFile (platform_file, uuid_ptr, local_file); + } + // Default to the local case local_file = platform_file; return Error(); @@ -176,8 +229,9 @@ PlatformLinux::GetFile (const FileSpec &platform_file, //------------------------------------------------------------------ /// Default Constructor //------------------------------------------------------------------ -PlatformLinux::PlatformLinux () : - Platform(true) +PlatformLinux::PlatformLinux (bool is_host) : + Platform(is_host), // This is the local host platform + m_remote_platform_sp () { } @@ -194,7 +248,17 @@ PlatformLinux::~PlatformLinux() bool PlatformLinux::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { - return Host::GetProcessInfo (pid, process_info); + bool success = false; + if (IsHost()) + { + success = Platform::GetProcessInfo (pid, process_info); + } + else + { + if (m_remote_platform_sp) + success = m_remote_platform_sp->GetProcessInfo (pid, process_info); + } + return success; } bool @@ -225,11 +289,9 @@ size_t PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) { - static const uint8_t g_i386_opcode[] = { 0xCC }; - ArchSpec arch = target.GetArchitecture(); - const uint8_t *opcode = NULL; - size_t opcode_size = 0; + const uint8_t *trap_opcode = NULL; + size_t trap_opcode_size = 0; switch (arch.GetCore()) { @@ -239,13 +301,39 @@ PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, case ArchSpec::eCore_x86_32_i386: case ArchSpec::eCore_x86_64_x86_64: - opcode = g_i386_opcode; - opcode_size = sizeof(g_i386_opcode); + { + static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; + trap_opcode = g_i386_breakpoint_opcode; + trap_opcode_size = sizeof(g_i386_breakpoint_opcode); + } break; } - bp_site->SetTrapOpcode(opcode, opcode_size); - return opcode_size; + if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) + return trap_opcode_size; + return 0; +} + +Error +PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info) +{ + Error error; + + if (IsHost()) + { + if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) + { + const bool is_localhost = true; + if (!launch_info.ConvertArgumentsForLaunchingInShell (error, is_localhost)) + return error; + } + error = Platform::LaunchProcess (launch_info); + } + else + { + error.SetErrorString ("the platform is not currently connected"); + } + return error; } lldb::ProcessSP @@ -255,7 +343,42 @@ PlatformLinux::Attach(ProcessAttachInfo &attach_info, Listener &listener, Error &error) { - ProcessSP processSP; - assert(!"Not implemented yet!"); - return processSP; + 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, + m_remote_platform_sp, + new_target_sp); + target = new_target_sp.get(); + } + else + error.Clear(); + + if (target && error.Success()) + { + debugger.GetTargetList().SetSelectedTarget(target); + + process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName()); + + if (process_sp) + error = process_sp->Attach (attach_info); + } + } + else + { + if (m_remote_platform_sp) + process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); + else + error.SetErrorString ("the platform is not currently connected"); + } + return process_sp; } diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h index eed5813edfe..da907bb4aa9 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h @@ -28,7 +28,7 @@ namespace lldb_private { static void Terminate (); - PlatformLinux (); + PlatformLinux (bool is_host); virtual ~PlatformLinux(); @@ -43,7 +43,10 @@ namespace lldb_private { GetPluginNameStatic(); static const char * - GetPluginDescriptionStatic(); + GetShortPluginNameStatic(bool is_host); + + static const char * + GetPluginDescriptionStatic(bool is_host); virtual const char * GetPluginName() @@ -74,7 +77,7 @@ namespace lldb_private { virtual const char * GetDescription () { - return GetPluginDescriptionStatic(); + return GetPluginDescriptionStatic(IsHost()); } virtual void @@ -94,6 +97,9 @@ namespace lldb_private { GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site); + virtual lldb_private::Error + LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); + virtual lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Listener &listener, Error &error); @@ -105,7 +111,7 @@ namespace lldb_private { } protected: - + lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote darwin OS private: DISALLOW_COPY_AND_ASSIGN (PlatformLinux); diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp index 6a0c54c36ad..2171a6dbb2f 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp @@ -87,7 +87,6 @@ ProcessLinux::ProcessLinux(Target& target, Listener &listener) m_in_limbo(false), m_exit_now(false) { - #if 0 // FIXME: Putting this code in the ctor and saving the byte order in a // member variable is a hack to avoid const qual issues in GetByteOrder. @@ -152,7 +151,6 @@ ProcessLinux::DoLaunch (Module *module, SetPrivateState(eStateLaunching); - uint32_t launch_flags = launch_info.GetFlags().Get(); const char *stdin_path = NULL; const char *stdout_path = NULL; const char *stderr_path = NULL; @@ -270,7 +268,13 @@ ProcessLinux::DoHalt(bool &caused_stop) Error ProcessLinux::DoDetach() { - return Error(1, eErrorTypeGeneric); + Error error; + + error = m_monitor->Detach(); + if (error.Success()) + SetPrivateState(eStateDetached); + + return error; } Error @@ -388,7 +392,7 @@ bool ProcessLinux::IsAlive() { StateType state = GetPrivateState(); - return state != eStateExited && state != eStateInvalid; + return state != eStateDetached && state != eStateExited && state != eStateInvalid; } size_t diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index 2a844623080..c154c5555db 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -722,6 +722,30 @@ KillOperation::Execute(ProcessMonitor *monitor) m_result = true; } +//------------------------------------------------------------------------------ +/// @class KillOperation +/// @brief Implements ProcessMonitor::BringProcessIntoLimbo. +class DetachOperation : public Operation +{ +public: + DetachOperation(Error &result) : m_error(result) { } + + void Execute(ProcessMonitor *monitor); + +private: + Error &m_error; +}; + +void +DetachOperation::Execute(ProcessMonitor *monitor) +{ + lldb::pid_t pid = monitor->GetPID(); + + if (ptrace(PT_DETACH, pid, NULL, 0) < 0) + m_error.SetErrorToErrno(); + +} + ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor) : m_monitor(monitor) { @@ -1220,7 +1244,7 @@ ProcessMonitor::MonitorCallback(void *callback_baton, ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, - const struct siginfo *info, lldb::pid_t pid) + const siginfo_t *info, lldb::pid_t pid) { ProcessMessage message; @@ -1261,7 +1285,7 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, - const struct siginfo *info, lldb::pid_t pid) + const siginfo_t *info, lldb::pid_t pid) { ProcessMessage message; int signo = info->si_signo; @@ -1312,7 +1336,7 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, } ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGSEGV(const struct siginfo *info) +ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info) { ProcessMessage::CrashReason reason; assert(info->si_signo == SIGSEGV); @@ -1336,7 +1360,7 @@ ProcessMonitor::GetCrashReasonForSIGSEGV(const struct siginfo *info) } ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGILL(const struct siginfo *info) +ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info) { ProcessMessage::CrashReason reason; assert(info->si_signo == SIGILL); @@ -1378,7 +1402,7 @@ ProcessMonitor::GetCrashReasonForSIGILL(const struct siginfo *info) } ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGFPE(const struct siginfo *info) +ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info) { ProcessMessage::CrashReason reason; assert(info->si_signo == SIGFPE); @@ -1420,7 +1444,7 @@ ProcessMonitor::GetCrashReasonForSIGFPE(const struct siginfo *info) } ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGBUS(const struct siginfo *info) +ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info) { ProcessMessage::CrashReason reason; assert(info->si_signo == SIGBUS); @@ -1646,7 +1670,9 @@ bool ProcessMonitor::Detach() { bool result; - KillOperation op(result); + lldb_private::Error error; + DetachOperation op(error); + result = error.Success(); DoOperation(&op); StopMonitor(); return result; diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h index ba6a76d7ab5..fdccb67745a 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h @@ -257,23 +257,23 @@ private: static ProcessMessage MonitorSIGTRAP(ProcessMonitor *monitor, - const struct siginfo *info, lldb::pid_t pid); + const siginfo_t *info, lldb::pid_t pid); static ProcessMessage MonitorSignal(ProcessMonitor *monitor, - const struct siginfo *info, lldb::pid_t pid); + const siginfo_t *info, lldb::pid_t pid); static ProcessMessage::CrashReason - GetCrashReasonForSIGSEGV(const struct siginfo *info); + GetCrashReasonForSIGSEGV(const siginfo_t *info); static ProcessMessage::CrashReason - GetCrashReasonForSIGILL(const struct siginfo *info); + GetCrashReasonForSIGILL(const siginfo_t *info); static ProcessMessage::CrashReason - GetCrashReasonForSIGFPE(const struct siginfo *info); + GetCrashReasonForSIGFPE(const siginfo_t *info); static ProcessMessage::CrashReason - GetCrashReasonForSIGBUS(const struct siginfo *info); + GetCrashReasonForSIGBUS(const siginfo_t *info); void DoOperation(Operation *op); |

