summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/linux/Host.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/linux/Host.cpp')
-rw-r--r--lldb/source/Host/linux/Host.cpp120
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
OpenPOWER on IntegriCloud