brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.5 KiB · 845b337 Raw
343 lines · cpp
1//===-- ProcessInfo.cpp ---------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Utility/ProcessInfo.h"10 11#include "lldb/Utility/ArchSpec.h"12#include "lldb/Utility/ScriptedMetadata.h"13#include "lldb/Utility/Stream.h"14#include "lldb/Utility/StreamString.h"15#include "lldb/Utility/UserIDResolver.h"16#include "llvm/ADT/SmallString.h"17 18#include <climits>19#include <optional>20 21using namespace lldb;22using namespace lldb_private;23 24ProcessInfo::ProcessInfo()25    : m_executable(), m_arguments(), m_environment(), m_arch(), m_listener_sp(),26      m_hijack_listener_sp(), m_shadow_listener_sp() {}27 28ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,29                         lldb::pid_t pid)30    : m_executable(name), m_arguments(), m_environment(), m_arch(arch),31      m_pid(pid), m_listener_sp(), m_hijack_listener_sp(),32      m_shadow_listener_sp() {}33 34void ProcessInfo::Clear() {35  m_executable.Clear();36  m_arguments.Clear();37  m_environment.clear();38  m_uid = UINT32_MAX;39  m_gid = UINT32_MAX;40  m_arch.Clear();41  m_pid = LLDB_INVALID_PROCESS_ID;42  m_scripted_metadata_sp.reset();43}44 45const char *ProcessInfo::GetName() const {46  return m_executable.GetFilename().GetCString();47}48 49llvm::StringRef ProcessInfo::GetNameAsStringRef() const {50  return m_executable.GetFilename().GetStringRef();51}52 53void ProcessInfo::Dump(Stream &s, Platform *platform) const {54  s << "Executable: " << GetName() << "\n";55  s << "Triple: ";56  m_arch.DumpTriple(s.AsRawOstream());57  s << "\n";58 59  s << "Arguments:\n";60  m_arguments.Dump(s);61 62  s.Format("Environment:\n{0}", m_environment);63}64 65void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,66                                    bool add_exe_file_as_first_arg) {67  if (exe_file) {68    m_executable = exe_file;69    if (add_exe_file_as_first_arg) {70      llvm::SmallString<128> filename;71      exe_file.GetPath(filename);72      if (!filename.empty())73        m_arguments.InsertArgumentAtIndex(0, filename);74    }75  } else {76    m_executable.Clear();77  }78}79 80llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; }81 82void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); }83 84void ProcessInfo::SetArguments(char const **argv,85                               bool first_arg_is_executable) {86  m_arguments.SetArguments(argv);87 88  // Is the first argument the executable?89  if (first_arg_is_executable) {90    const char *first_arg = m_arguments.GetArgumentAtIndex(0);91    if (first_arg) {92      // Yes the first argument is an executable, set it as the executable in93      // the launch options. Don't resolve the file path as the path could be a94      // remote platform path95      m_executable.SetFile(first_arg, FileSpec::Style::native);96    }97  }98}99 100void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) {101  // Copy all arguments102  m_arguments = args;103 104  // Is the first argument the executable?105  if (first_arg_is_executable) {106    const char *first_arg = m_arguments.GetArgumentAtIndex(0);107    if (first_arg) {108      // Yes the first argument is an executable, set it as the executable in109      // the launch options. Don't resolve the file path as the path could be a110      // remote platform path111      m_executable.SetFile(first_arg, FileSpec::Style::native);112    }113  }114}115 116bool ProcessInfo::IsScriptedProcess() const {117  return m_scripted_metadata_sp && *m_scripted_metadata_sp;118}119 120void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const {121  if (m_pid != LLDB_INVALID_PROCESS_ID)122    s.Printf("    pid = %" PRIu64 "\n", m_pid);123 124  if (ParentProcessIDIsValid())125    s.Printf(" parent = %" PRIu64 "\n", GetParentProcessID());126 127  if (m_executable) {128    s.Printf("   name = %s\n", m_executable.GetFilename().GetCString());129    s.PutCString("   file = ");130    m_executable.Dump(s.AsRawOstream());131    s.EOL();132  }133  const uint32_t argc = m_arguments.GetArgumentCount();134  if (argc > 0) {135    for (uint32_t i = 0; i < argc; i++) {136      const char *arg = m_arguments.GetArgumentAtIndex(i);137      if (i < 10)138        s.Printf(" arg[%u] = %s\n", i, arg);139      else140        s.Printf("arg[%u] = %s\n", i, arg);141    }142  }143 144  s.Format("{0}", m_environment);145 146  if (m_arch.IsValid()) {147    s.Printf("   arch = ");148    m_arch.DumpTriple(s.AsRawOstream());149    s.EOL();150  }151 152  if (UserIDIsValid()) {153    s.Format("    uid = {0,-5} ({1})\n", GetUserID(),154             resolver.GetUserName(GetUserID()).value_or(""));155  }156  if (GroupIDIsValid()) {157    s.Format("    gid = {0,-5} ({1})\n", GetGroupID(),158             resolver.GetGroupName(GetGroupID()).value_or(""));159  }160  if (EffectiveUserIDIsValid()) {161    s.Format("   euid = {0,-5} ({1})\n", GetEffectiveUserID(),162             resolver.GetUserName(GetEffectiveUserID()).value_or(""));163  }164  if (EffectiveGroupIDIsValid()) {165    s.Format("   egid = {0,-5} ({1})\n", GetEffectiveGroupID(),166             resolver.GetGroupName(GetEffectiveGroupID()).value_or(""));167  }168}169 170void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,171                                          bool verbose) {172  const char *label;173  if (show_args || verbose)174    label = "ARGUMENTS";175  else176    label = "NAME";177 178  if (verbose) {179    s.Printf("PID    PARENT USER       GROUP      EFF USER   EFF GROUP  TRIPLE "180             "                        %s\n",181             label);182    s.PutCString(183        "====== ====== ========== ========== ========== ========== "184        "============================== ============================\n");185  } else {186    s.Printf("PID    PARENT USER       TRIPLE                         %s\n",187             label);188    s.PutCString("====== ====== ========== ============================== "189                 "============================\n");190  }191}192 193void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,194                                         bool show_args, bool verbose) const {195  if (m_pid != LLDB_INVALID_PROCESS_ID) {196    s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid,197             (ParentProcessIDIsValid()) ? GetParentProcessID() : 0);198 199    StreamString arch_strm;200    if (m_arch.IsValid())201      m_arch.DumpTriple(arch_strm.AsRawOstream());202 203    auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,204                     uint32_t (ProcessInstanceInfo::*getID)() const,205                     std::optional<llvm::StringRef> (UserIDResolver::*getName)(206                         UserIDResolver::id_t id)) {207      const char *format = "{0,-10} ";208      if (!(this->*isValid)()) {209        s.Format(format, "");210        return;211      }212      uint32_t id = (this->*getID)();213      if (auto name = (resolver.*getName)(id))214        s.Format(format, *name);215      else216        s.Format(format, id);217    };218    if (verbose) {219      print(&ProcessInstanceInfo::UserIDIsValid,220            &ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);221      print(&ProcessInstanceInfo::GroupIDIsValid,222            &ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);223      print(&ProcessInstanceInfo::EffectiveUserIDIsValid,224            &ProcessInstanceInfo::GetEffectiveUserID,225            &UserIDResolver::GetUserName);226      print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,227            &ProcessInstanceInfo::GetEffectiveGroupID,228            &UserIDResolver::GetGroupName);229 230      s.Printf("%-30s ", arch_strm.GetData());231    } else {232      print(&ProcessInstanceInfo::EffectiveUserIDIsValid,233            &ProcessInstanceInfo::GetEffectiveUserID,234            &UserIDResolver::GetUserName);235      s.Printf("%-30s ", arch_strm.GetData());236    }237 238    if (verbose || show_args) {239      s.PutCString(m_arg0);240      const uint32_t argc = m_arguments.GetArgumentCount();241      for (uint32_t i = 0; i < argc; i++) {242        s.PutChar(' ');243        s.PutCString(m_arguments.GetArgumentAtIndex(i));244      }245    } else {246      s.PutCString(GetName());247    }248 249    s.EOL();250  }251}252 253bool ProcessInstanceInfoMatch::ArchitectureMatches(254    const ArchSpec &arch_spec) const {255  return !m_match_info.GetArchitecture().IsValid() ||256         m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);257}258 259bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {260  if (m_name_match_type == NameMatch::Ignore)261    return true;262  const char *match_name = m_match_info.GetName();263  if (!match_name)264    return true;265 266  return lldb_private::NameMatches(process_name, m_name_match_type, match_name);267}268 269bool ProcessInstanceInfoMatch::ProcessIDsMatch(270    const ProcessInstanceInfo &proc_info) const {271  if (m_match_info.ProcessIDIsValid() &&272      m_match_info.GetProcessID() != proc_info.GetProcessID())273    return false;274 275  if (m_match_info.ParentProcessIDIsValid() &&276      m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())277    return false;278  return true;279}280 281bool ProcessInstanceInfoMatch::UserIDsMatch(282    const ProcessInstanceInfo &proc_info) const {283  if (m_match_info.UserIDIsValid() &&284      m_match_info.GetUserID() != proc_info.GetUserID())285    return false;286 287  if (m_match_info.GroupIDIsValid() &&288      m_match_info.GetGroupID() != proc_info.GetGroupID())289    return false;290 291  if (m_match_info.EffectiveUserIDIsValid() &&292      m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())293    return false;294 295  if (m_match_info.EffectiveGroupIDIsValid() &&296      m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())297    return false;298  return true;299}300bool ProcessInstanceInfoMatch::Matches(301    const ProcessInstanceInfo &proc_info) const {302  return ArchitectureMatches(proc_info.GetArchitecture()) &&303         ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&304         NameMatches(proc_info.GetName());305}306 307bool ProcessInstanceInfoMatch::MatchAllProcesses() const {308  if (m_name_match_type != NameMatch::Ignore)309    return false;310 311  if (m_match_info.ProcessIDIsValid())312    return false;313 314  if (m_match_info.ParentProcessIDIsValid())315    return false;316 317  if (m_match_info.UserIDIsValid())318    return false;319 320  if (m_match_info.GroupIDIsValid())321    return false;322 323  if (m_match_info.EffectiveUserIDIsValid())324    return false;325 326  if (m_match_info.EffectiveGroupIDIsValid())327    return false;328 329  if (m_match_info.GetArchitecture().IsValid())330    return false;331 332  if (m_match_all_users)333    return false;334 335  return true;336}337 338void ProcessInstanceInfoMatch::Clear() {339  m_match_info.Clear();340  m_name_match_type = NameMatch::Ignore;341  m_match_all_users = false;342}343