static bool GetNetBSDProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr, ProcessInstanceInfo &process_info) { if (!process_info.ProcessIDIsValid()) return false; int pid = process_info.GetProcessID(); int mib[4] = { CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV }; char arg_data[8192]; size_t arg_data_size = sizeof(arg_data); if (::sysctl (mib, 4, arg_data, &arg_data_size , NULL, 0) != 0) return false; DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *)); lldb::offset_t offset = 0; const char *cstr; cstr = data.GetCStr (&offset); if (!cstr) return false; process_info.GetExecutableFile().SetFile(cstr, false); if (!(match_info_ptr == NULL || NameMatches (process_info.GetExecutableFile().GetFilename().GetCString(), match_info_ptr->GetNameMatchType(), match_info_ptr->GetProcessInfo().GetName()))) return false; Args &proc_args = process_info.GetArguments(); while (1) { const uint8_t *p = data.PeekData(offset, 1); while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { ++offset; p = data.PeekData(offset, 1); } if (p == NULL || offset >= arg_data_size) break; cstr = data.GetCStr(&offset); if (!cstr) break; proc_args.AppendArgument(cstr); } return true; }
void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse( const ProcessInstanceInfo &proc_info, StreamString &response) { response.Printf( "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", proc_info.GetProcessID(), proc_info.GetParentProcessID(), proc_info.GetUserID(), proc_info.GetGroupID(), proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID()); response.PutCString("name:"); response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString()); response.PutChar(';'); const ArchSpec &proc_arch = proc_info.GetArchitecture(); if (proc_arch.IsValid()) { const llvm::Triple &proc_triple = proc_arch.GetTriple(); response.PutCString("triple:"); response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); response.PutChar(';'); } }
static bool GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid) { tracerpid = 0; process_info.Clear(); ::memset (&stat_info, 0, sizeof(stat_info)); stat_info.ppid = LLDB_INVALID_PROCESS_ID; // 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) return false; ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1); if (len <= 0) return false; // readlink does not append a null byte. exe_path[len] = 0; // If the binary has been deleted, the link name has " (deleted)" appended. // Remove if there. 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; } else { GetELFProcessCPUType (exe_path, process_info); } process_info.SetProcessID(pid); 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; } // Read /proc/$PID/stat to get our parent pid. if (ReadProcPseudoFileStat (pid, stat_info)) { process_info.SetParentProcessID (stat_info.ppid); } // Get User and Group IDs and get tracer pid. GetLinuxProcessUserAndGroup (pid, process_info, tracerpid); return true; }
static bool GetProcessAndStatInfo(::pid_t pid, ProcessInstanceInfo &process_info, ProcessState &State, ::pid_t &tracerpid) { tracerpid = 0; process_info.Clear(); Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); // We can't use getProcFile here because proc/[pid]/exe is a symbolic link. llvm::SmallString<64> ProcExe; (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe); std::string ExePath(PATH_MAX, '\0'); ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX); if (len <= 0) { LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid, Status(errno, eErrorTypePOSIX)); return false; } ExePath.resize(len); // If the binary has been deleted, the link name has " (deleted)" appended. // Remove if there. llvm::StringRef PathRef = ExePath; PathRef.consume_back(" (deleted)"); GetELFProcessCPUType(PathRef, process_info); // Get the process environment. auto BufferOrError = getProcFile(pid, "environ"); if (!BufferOrError) return false; std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError); // Get the command line used to start the process. BufferOrError = getProcFile(pid, "cmdline"); if (!BufferOrError) return false; std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError); // Get User and Group IDs and get tracer pid. if (!GetStatusInfo(pid, process_info, State, tracerpid)) return false; process_info.SetProcessID(pid); process_info.GetExecutableFile().SetFile(PathRef, false); process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture()); llvm::StringRef Rest = Environ->getBuffer(); while (!Rest.empty()) { llvm::StringRef Var; std::tie(Var, Rest) = Rest.split('\0'); process_info.GetEnvironmentEntries().AppendArgument(Var); } llvm::StringRef Arg0; std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0'); process_info.SetArg0(Arg0); while (!Rest.empty()) { llvm::StringRef Arg; std::tie(Arg, Rest) = Rest.split('\0'); process_info.GetArguments().AppendArgument(Arg); } return true; }