diff options
Diffstat (limited to 'lldb/source/Host/linux/Host.cpp')
| -rw-r--r-- | lldb/source/Host/linux/Host.cpp | 120 |
1 files changed, 97 insertions, 23 deletions
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 |

