diff options
| author | Andrew Kaylor <andrew.kaylor@intel.com> | 2013-05-07 22:46:38 +0000 |
|---|---|---|
| committer | Andrew Kaylor <andrew.kaylor@intel.com> | 2013-05-07 22:46:38 +0000 |
| commit | bf9b4c171a6481ef1341b754c67da82559b76450 (patch) | |
| tree | 1551eecaf552f0020a5d629d7fb49d886598fcb2 | |
| parent | 8f1fb6f03df0e79ac6ee6119327f0edf9870554b (diff) | |
| download | bcm5719-llvm-bf9b4c171a6481ef1341b754c67da82559b76450.tar.gz bcm5719-llvm-bf9b4c171a6481ef1341b754c67da82559b76450.zip | |
Adding support for process attach by pid on Linux.
llvm-svn: 181374
6 files changed, 142 insertions, 30 deletions
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index f5f8dd2284d..fc84dfd677e 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -1189,7 +1189,7 @@ Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstance } #endif -#if !defined (__APPLE__) && !defined (__FreeBSD__) +#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined(__linux__) bool Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index cddc5dbb71f..c173a25dfe2 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -28,31 +28,11 @@ using namespace lldb; using namespace lldb_private; -bool -Host::GetOSVersion(uint32_t &major, - uint32_t &minor, - uint32_t &update) +namespace { - struct utsname un; - int status; - - if (uname(&un)) - return false; - - status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update); - return status == 3; -} - -Error -Host::LaunchProcess (ProcessLaunchInfo &launch_info) -{ - Error error; - assert(!"Not implemented yet!!!"); - return error; -} lldb::DataBufferSP -Host::GetAuxvData(lldb_private::Process *process) +ReadProcPseudoFile(lldb::pid_t pid, const char *name) { static const size_t path_size = 128; static char path[path_size]; @@ -65,7 +45,7 @@ Host::GetAuxvData(lldb_private::Process *process) // dynamically generated by the kernel) which is incompatible with the // current ReadFileContents implementation. Therefore we simply stream the // data into a DataBuffer ourselves. - if (snprintf(path, path_size, "/proc/%" PRIu64 "/auxv", process->GetID()) < 0) + if (snprintf(path, path_size, "/proc/%" PRIu64 "/%s", pid, name) < 0) return buf_sp; if ((fd = open(path, O_RDONLY, 0)) < 0) @@ -96,3 +76,97 @@ Host::GetAuxvData(lldb_private::Process *process) return buf_sp; } + +} // anonymous namespace + +bool +Host::GetOSVersion(uint32_t &major, + uint32_t &minor, + uint32_t &update) +{ + struct utsname un; + int status; + + if (uname(&un)) + return false; + + status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update); + return status == 3; +} + +Error +Host::LaunchProcess (ProcessLaunchInfo &launch_info) +{ + Error error; + assert(!"Not implemented yet!!!"); + return error; +} + +lldb::DataBufferSP +Host::GetAuxvData(lldb_private::Process *process) +{ + return ReadProcPseudoFile(process->GetID(), "auxv"); +} + + +bool +Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) +{ + process_info.Clear(); + process_info.SetProcessID(pid); + + // Architecture is intentionally omitted because that's better resolved + // in other places (see ProcessPOSIX::DoAttachWithID(). + + // Use special code here because proc/[pid]/exe is a symbolic link. + char link_path[PATH_MAX]; + char exe_path[PATH_MAX] = ""; + if (snprintf(link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) > 0) + { + ssize_t len = readlink(link_path, exe_path, sizeof(exe_path) - 1); + if (len > 0) + exe_path[len] = 0; + + static const ssize_t deleted_len = strlen(" (deleted)"); + if (len > deleted_len && + !strcmp(exe_path + len - deleted_len, " (deleted)")) + { + exe_path[len - deleted_len] = 0; + } + } + process_info.GetExecutableFile().SetFile(exe_path, false); + + lldb::DataBufferSP buf_sp; + + // Get the process environment. + buf_sp = ReadProcPseudoFile(pid, "environ"); + Args &info_env = process_info.GetEnvironmentEntries(); + char *next_var = (char *)buf_sp->GetBytes(); + char *end_buf = next_var + buf_sp->GetByteSize(); + while (next_var < end_buf && 0 != *next_var) + { + info_env.AppendArgument(next_var); + next_var += strlen(next_var) + 1; + } + + // Get the commond line used to start the process. + buf_sp = ReadProcPseudoFile(pid, "cmdline"); + + // Grab Arg0 first. + char *cmd = (char *)buf_sp->GetBytes(); + process_info.SetArg0(cmd); + + // Now process any remaining arguments. + Args &info_args = process_info.GetArguments(); + char *next_arg = cmd + strlen(cmd) + 1; + end_buf = cmd + buf_sp->GetByteSize(); + while (next_arg < end_buf && 0 != *next_arg) + { + info_args.AppendArgument(next_arg); + next_arg += strlen(next_arg) + 1; + } + + // FIXME: Parse /proc/<pid>/status to get uid, gid, euid, egid and parent_pid + + return true; +}
\ No newline at end of file diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index e832739bdc0..3e1b52938f4 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -59,7 +59,12 @@ DYLDRendezvous::DYLDRendezvous(Process *process) m_removed_soentries() { // Cache a copy of the executable path - m_process->GetTarget().GetExecutableModule().get()->GetFileSpec().GetPath(m_exe_path, PATH_MAX); + if (m_process) + { + Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer(); + if (exe_mod) + exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX); + } } bool diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index f0105685de5..471843b3f99 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -22,6 +22,7 @@ #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/Target.h" #include "ProcessPOSIX.h" @@ -99,7 +100,8 @@ ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name) ModuleSP exe_module_sp(target.GetExecutableModule()); if (exe_module_sp.get()) return exe_module_sp->GetFileSpec().Exists(); - return false; + // If there is no executable module, we return true since we might be preparing to attach. + return true; } Error @@ -117,7 +119,38 @@ ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) if (!error.Success()) return error; + PlatformSP platform_sp (m_target.GetPlatform ()); + assert (platform_sp.get()); + if (!platform_sp) + return error; // FIXME: Detatch? + + // Find out what we can about this process + ProcessInstanceInfo process_info; + platform_sp->GetProcessInfo (pid, process_info); + + // Resolve the executable module + ModuleSP exe_module_sp; + FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); + error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), + m_target.GetArchitecture(), + exe_module_sp, + executable_search_paths.GetSize() ? &executable_search_paths : NULL); + + // Fix the target architecture if necessary + const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); + if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch)) + m_target.SetArchitecture(module_arch); + + // Initialize the target module list + m_target.SetExecutableModule (exe_module_sp, true); + + if (!error.Success()) + return error; + + SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); + SetID(pid); + return error; } diff --git a/lldb/test/functionalities/connect_remote/TestConnectRemote.py b/lldb/test/functionalities/connect_remote/TestConnectRemote.py index e36647e27c2..2ec3bfba2f7 100644 --- a/lldb/test/functionalities/connect_remote/TestConnectRemote.py +++ b/lldb/test/functionalities/connect_remote/TestConnectRemote.py @@ -31,7 +31,10 @@ class ConnectRemoteTestCase(TestBase): fakeserver.expect_exact('Listening on localhost:12345') # Connect to the fake server.... - self.runCmd("process connect connect://localhost:12345") + if sys.platform.startswith("linux"): + self.runCmd("process connect -p gdb-remote connect://localhost:12345") + else: + self.runCmd("process connect connect://localhost:12345") if __name__ == '__main__': diff --git a/lldb/test/functionalities/process_attach/TestProcessAttach.py b/lldb/test/functionalities/process_attach/TestProcessAttach.py index 49c9ef4348a..74841bfee0a 100644 --- a/lldb/test/functionalities/process_attach/TestProcessAttach.py +++ b/lldb/test/functionalities/process_attach/TestProcessAttach.py @@ -19,7 +19,6 @@ class ProcessAttachTestCase(TestBase): self.buildDsym() self.process_attach_by_id() - @expectedFailureLinux # lldb is unable to attach to process by id @dwarf_test def test_attach_to_process_by_id_with_dwarf(self): """Test attach by process id""" @@ -49,8 +48,6 @@ class ProcessAttachTestCase(TestBase): exe = os.path.join(os.getcwd(), "a.out") - #target = self.dbg.CreateTarget(exe) - # Spawn a new process popen = self.spawnSubprocess(exe) self.addTearDownHook(self.cleanupSubprocesses) |

