Path: blob/main/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp
39587 views
//===-- ProcessInfo.cpp ---------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Utility/ProcessInfo.h"910#include "lldb/Utility/ArchSpec.h"11#include "lldb/Utility/ScriptedMetadata.h"12#include "lldb/Utility/Stream.h"13#include "lldb/Utility/StreamString.h"14#include "lldb/Utility/UserIDResolver.h"15#include "llvm/ADT/SmallString.h"1617#include <climits>18#include <optional>1920using namespace lldb;21using namespace lldb_private;2223ProcessInfo::ProcessInfo()24: m_executable(), m_arguments(), m_environment(), m_arch(), m_listener_sp(),25m_hijack_listener_sp(), m_shadow_listener_sp() {}2627ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,28lldb::pid_t pid)29: m_executable(name), m_arguments(), m_environment(), m_arch(arch),30m_pid(pid), m_listener_sp(), m_hijack_listener_sp(),31m_shadow_listener_sp() {}3233void ProcessInfo::Clear() {34m_executable.Clear();35m_arguments.Clear();36m_environment.clear();37m_uid = UINT32_MAX;38m_gid = UINT32_MAX;39m_arch.Clear();40m_pid = LLDB_INVALID_PROCESS_ID;41m_scripted_metadata_sp.reset();42}4344const char *ProcessInfo::GetName() const {45return m_executable.GetFilename().GetCString();46}4748llvm::StringRef ProcessInfo::GetNameAsStringRef() const {49return m_executable.GetFilename().GetStringRef();50}5152void ProcessInfo::Dump(Stream &s, Platform *platform) const {53s << "Executable: " << GetName() << "\n";54s << "Triple: ";55m_arch.DumpTriple(s.AsRawOstream());56s << "\n";5758s << "Arguments:\n";59m_arguments.Dump(s);6061s.Format("Environment:\n{0}", m_environment);62}6364void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,65bool add_exe_file_as_first_arg) {66if (exe_file) {67m_executable = exe_file;68if (add_exe_file_as_first_arg) {69llvm::SmallString<128> filename;70exe_file.GetPath(filename);71if (!filename.empty())72m_arguments.InsertArgumentAtIndex(0, filename);73}74} else {75m_executable.Clear();76}77}7879llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; }8081void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); }8283void ProcessInfo::SetArguments(char const **argv,84bool first_arg_is_executable) {85m_arguments.SetArguments(argv);8687// Is the first argument the executable?88if (first_arg_is_executable) {89const char *first_arg = m_arguments.GetArgumentAtIndex(0);90if (first_arg) {91// Yes the first argument is an executable, set it as the executable in92// the launch options. Don't resolve the file path as the path could be a93// remote platform path94m_executable.SetFile(first_arg, FileSpec::Style::native);95}96}97}9899void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) {100// Copy all arguments101m_arguments = args;102103// Is the first argument the executable?104if (first_arg_is_executable) {105const char *first_arg = m_arguments.GetArgumentAtIndex(0);106if (first_arg) {107// Yes the first argument is an executable, set it as the executable in108// the launch options. Don't resolve the file path as the path could be a109// remote platform path110m_executable.SetFile(first_arg, FileSpec::Style::native);111}112}113}114115bool ProcessInfo::IsScriptedProcess() const {116return m_scripted_metadata_sp && *m_scripted_metadata_sp;117}118119void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const {120if (m_pid != LLDB_INVALID_PROCESS_ID)121s.Printf(" pid = %" PRIu64 "\n", m_pid);122123if (ParentProcessIDIsValid())124s.Printf(" parent = %" PRIu64 "\n", GetParentProcessID());125126if (m_executable) {127s.Printf(" name = %s\n", m_executable.GetFilename().GetCString());128s.PutCString(" file = ");129m_executable.Dump(s.AsRawOstream());130s.EOL();131}132const uint32_t argc = m_arguments.GetArgumentCount();133if (argc > 0) {134for (uint32_t i = 0; i < argc; i++) {135const char *arg = m_arguments.GetArgumentAtIndex(i);136if (i < 10)137s.Printf(" arg[%u] = %s\n", i, arg);138else139s.Printf("arg[%u] = %s\n", i, arg);140}141}142143s.Format("{0}", m_environment);144145if (m_arch.IsValid()) {146s.Printf(" arch = ");147m_arch.DumpTriple(s.AsRawOstream());148s.EOL();149}150151if (UserIDIsValid()) {152s.Format(" uid = {0,-5} ({1})\n", GetUserID(),153resolver.GetUserName(GetUserID()).value_or(""));154}155if (GroupIDIsValid()) {156s.Format(" gid = {0,-5} ({1})\n", GetGroupID(),157resolver.GetGroupName(GetGroupID()).value_or(""));158}159if (EffectiveUserIDIsValid()) {160s.Format(" euid = {0,-5} ({1})\n", GetEffectiveUserID(),161resolver.GetUserName(GetEffectiveUserID()).value_or(""));162}163if (EffectiveGroupIDIsValid()) {164s.Format(" egid = {0,-5} ({1})\n", GetEffectiveGroupID(),165resolver.GetGroupName(GetEffectiveGroupID()).value_or(""));166}167}168169void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,170bool verbose) {171const char *label;172if (show_args || verbose)173label = "ARGUMENTS";174else175label = "NAME";176177if (verbose) {178s.Printf("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE "179" %s\n",180label);181s.PutCString(182"====== ====== ========== ========== ========== ========== "183"============================== ============================\n");184} else {185s.Printf("PID PARENT USER TRIPLE %s\n",186label);187s.PutCString("====== ====== ========== ============================== "188"============================\n");189}190}191192void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,193bool show_args, bool verbose) const {194if (m_pid != LLDB_INVALID_PROCESS_ID) {195s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid,196(ParentProcessIDIsValid()) ? GetParentProcessID() : 0);197198StreamString arch_strm;199if (m_arch.IsValid())200m_arch.DumpTriple(arch_strm.AsRawOstream());201202auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,203uint32_t (ProcessInstanceInfo::*getID)() const,204std::optional<llvm::StringRef> (UserIDResolver::*getName)(205UserIDResolver::id_t id)) {206const char *format = "{0,-10} ";207if (!(this->*isValid)()) {208s.Format(format, "");209return;210}211uint32_t id = (this->*getID)();212if (auto name = (resolver.*getName)(id))213s.Format(format, *name);214else215s.Format(format, id);216};217if (verbose) {218print(&ProcessInstanceInfo::UserIDIsValid,219&ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);220print(&ProcessInstanceInfo::GroupIDIsValid,221&ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);222print(&ProcessInstanceInfo::EffectiveUserIDIsValid,223&ProcessInstanceInfo::GetEffectiveUserID,224&UserIDResolver::GetUserName);225print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,226&ProcessInstanceInfo::GetEffectiveGroupID,227&UserIDResolver::GetGroupName);228229s.Printf("%-30s ", arch_strm.GetData());230} else {231print(&ProcessInstanceInfo::EffectiveUserIDIsValid,232&ProcessInstanceInfo::GetEffectiveUserID,233&UserIDResolver::GetUserName);234s.Printf("%-30s ", arch_strm.GetData());235}236237if (verbose || show_args) {238s.PutCString(m_arg0);239const uint32_t argc = m_arguments.GetArgumentCount();240for (uint32_t i = 0; i < argc; i++) {241s.PutChar(' ');242s.PutCString(m_arguments.GetArgumentAtIndex(i));243}244} else {245s.PutCString(GetName());246}247248s.EOL();249}250}251252bool ProcessInstanceInfoMatch::ArchitectureMatches(253const ArchSpec &arch_spec) const {254return !m_match_info.GetArchitecture().IsValid() ||255m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);256}257258bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {259if (m_name_match_type == NameMatch::Ignore)260return true;261const char *match_name = m_match_info.GetName();262if (!match_name)263return true;264265return lldb_private::NameMatches(process_name, m_name_match_type, match_name);266}267268bool ProcessInstanceInfoMatch::ProcessIDsMatch(269const ProcessInstanceInfo &proc_info) const {270if (m_match_info.ProcessIDIsValid() &&271m_match_info.GetProcessID() != proc_info.GetProcessID())272return false;273274if (m_match_info.ParentProcessIDIsValid() &&275m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())276return false;277return true;278}279280bool ProcessInstanceInfoMatch::UserIDsMatch(281const ProcessInstanceInfo &proc_info) const {282if (m_match_info.UserIDIsValid() &&283m_match_info.GetUserID() != proc_info.GetUserID())284return false;285286if (m_match_info.GroupIDIsValid() &&287m_match_info.GetGroupID() != proc_info.GetGroupID())288return false;289290if (m_match_info.EffectiveUserIDIsValid() &&291m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())292return false;293294if (m_match_info.EffectiveGroupIDIsValid() &&295m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())296return false;297return true;298}299bool ProcessInstanceInfoMatch::Matches(300const ProcessInstanceInfo &proc_info) const {301return ArchitectureMatches(proc_info.GetArchitecture()) &&302ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&303NameMatches(proc_info.GetName());304}305306bool ProcessInstanceInfoMatch::MatchAllProcesses() const {307if (m_name_match_type != NameMatch::Ignore)308return false;309310if (m_match_info.ProcessIDIsValid())311return false;312313if (m_match_info.ParentProcessIDIsValid())314return false;315316if (m_match_info.UserIDIsValid())317return false;318319if (m_match_info.GroupIDIsValid())320return false;321322if (m_match_info.EffectiveUserIDIsValid())323return false;324325if (m_match_info.EffectiveGroupIDIsValid())326return false;327328if (m_match_info.GetArchitecture().IsValid())329return false;330331if (m_match_all_users)332return false;333334return true;335}336337void ProcessInstanceInfoMatch::Clear() {338m_match_info.Clear();339m_name_match_type = NameMatch::Ignore;340m_match_all_users = false;341}342343344