1 //===-- ProcessInfo.h -------------------------------------------*- C++ -*-===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_UTILITY_PROCESSINFO_H 10 #define LLDB_UTILITY_PROCESSINFO_H 11 12 #include "lldb/Utility/ArchSpec.h" 13 #include "lldb/Utility/Args.h" 14 #include "lldb/Utility/Environment.h" 15 #include "lldb/Utility/FileSpec.h" 16 #include "lldb/Utility/NameMatches.h" 17 #include "lldb/Utility/StructuredData.h" 18 #include <vector> 19 20 namespace lldb_private { 21 22 class UserIDResolver; 23 24 // ProcessInfo 25 // 26 // A base class for information for a process. This can be used to fill 27 // out information for a process prior to launching it, or it can be used for 28 // an instance of a process and can be filled in with the existing values for 29 // that process. 30 class ProcessInfo { 31 public: 32 ProcessInfo(); 33 34 ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid); 35 36 void Clear(); 37 38 const char *GetName() const; 39 40 llvm::StringRef GetNameAsStringRef() const; 41 GetExecutableFile()42 FileSpec &GetExecutableFile() { return m_executable; } 43 44 void SetExecutableFile(const FileSpec &exe_file, 45 bool add_exe_file_as_first_arg); 46 GetExecutableFile()47 const FileSpec &GetExecutableFile() const { return m_executable; } 48 GetUserID()49 uint32_t GetUserID() const { return m_uid; } 50 GetGroupID()51 uint32_t GetGroupID() const { return m_gid; } 52 UserIDIsValid()53 bool UserIDIsValid() const { return m_uid != UINT32_MAX; } 54 GroupIDIsValid()55 bool GroupIDIsValid() const { return m_gid != UINT32_MAX; } 56 SetUserID(uint32_t uid)57 void SetUserID(uint32_t uid) { m_uid = uid; } 58 SetGroupID(uint32_t gid)59 void SetGroupID(uint32_t gid) { m_gid = gid; } 60 GetArchitecture()61 ArchSpec &GetArchitecture() { return m_arch; } 62 GetArchitecture()63 const ArchSpec &GetArchitecture() const { return m_arch; } 64 SetArchitecture(const ArchSpec & arch)65 void SetArchitecture(const ArchSpec &arch) { m_arch = arch; } 66 GetProcessID()67 lldb::pid_t GetProcessID() const { return m_pid; } 68 SetProcessID(lldb::pid_t pid)69 void SetProcessID(lldb::pid_t pid) { m_pid = pid; } 70 ProcessIDIsValid()71 bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; } 72 73 void Dump(Stream &s, Platform *platform) const; 74 GetArguments()75 Args &GetArguments() { return m_arguments; } 76 GetArguments()77 const Args &GetArguments() const { return m_arguments; } 78 79 llvm::StringRef GetArg0() const; 80 81 void SetArg0(llvm::StringRef arg); 82 83 void SetArguments(const Args &args, bool first_arg_is_executable); 84 85 void SetArguments(char const **argv, bool first_arg_is_executable); 86 GetEnvironment()87 Environment &GetEnvironment() { return m_environment; } GetEnvironment()88 const Environment &GetEnvironment() const { return m_environment; } 89 90 bool IsScriptedProcess() const; 91 GetScriptedMetadata()92 lldb::ScriptedMetadataSP GetScriptedMetadata() const { 93 return m_scripted_metadata_sp; 94 } 95 SetScriptedMetadata(lldb::ScriptedMetadataSP metadata_sp)96 void SetScriptedMetadata(lldb::ScriptedMetadataSP metadata_sp) { 97 m_scripted_metadata_sp = metadata_sp; 98 } 99 100 // Get and set the actual listener that will be used for the process events GetListener()101 lldb::ListenerSP GetListener() const { return m_listener_sp; } 102 SetListener(const lldb::ListenerSP & listener_sp)103 void SetListener(const lldb::ListenerSP &listener_sp) { 104 m_listener_sp = listener_sp; 105 } 106 GetHijackListener()107 lldb::ListenerSP GetHijackListener() const { return m_hijack_listener_sp; } 108 SetHijackListener(const lldb::ListenerSP & listener_sp)109 void SetHijackListener(const lldb::ListenerSP &listener_sp) { 110 m_hijack_listener_sp = listener_sp; 111 } 112 GetShadowListener()113 lldb::ListenerSP GetShadowListener() const { return m_shadow_listener_sp; } 114 SetShadowListener(const lldb::ListenerSP & listener_sp)115 void SetShadowListener(const lldb::ListenerSP &listener_sp) { 116 m_shadow_listener_sp = listener_sp; 117 } 118 119 protected: 120 FileSpec m_executable; 121 std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. 122 // Not all process plug-ins support specifying an argv[0] that differs from 123 // the resolved platform executable (which is in m_executable) 124 Args m_arguments; // All program arguments except argv[0] 125 Environment m_environment; 126 uint32_t m_uid = UINT32_MAX; 127 uint32_t m_gid = UINT32_MAX; 128 ArchSpec m_arch; 129 lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID; 130 lldb::ScriptedMetadataSP m_scripted_metadata_sp = nullptr; 131 lldb::ListenerSP m_listener_sp = nullptr; 132 lldb::ListenerSP m_hijack_listener_sp = nullptr; 133 lldb::ListenerSP m_shadow_listener_sp = nullptr; 134 }; 135 136 // ProcessInstanceInfo 137 // 138 // Describes an existing process and any discoverable information that pertains 139 // to that process. 140 class ProcessInstanceInfo : public ProcessInfo { 141 public: 142 ProcessInstanceInfo() = default; 143 ProcessInstanceInfo(const char * name,const ArchSpec & arch,lldb::pid_t pid)144 ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) 145 : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), 146 m_parent_pid(LLDB_INVALID_PROCESS_ID) {} 147 Clear()148 void Clear() { 149 ProcessInfo::Clear(); 150 m_euid = UINT32_MAX; 151 m_egid = UINT32_MAX; 152 m_parent_pid = LLDB_INVALID_PROCESS_ID; 153 } 154 GetEffectiveUserID()155 uint32_t GetEffectiveUserID() const { return m_euid; } 156 GetEffectiveGroupID()157 uint32_t GetEffectiveGroupID() const { return m_egid; } 158 EffectiveUserIDIsValid()159 bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; } 160 EffectiveGroupIDIsValid()161 bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; } 162 SetEffectiveUserID(uint32_t uid)163 void SetEffectiveUserID(uint32_t uid) { m_euid = uid; } 164 SetEffectiveGroupID(uint32_t gid)165 void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; } 166 GetParentProcessID()167 lldb::pid_t GetParentProcessID() const { return m_parent_pid; } 168 SetParentProcessID(lldb::pid_t pid)169 void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } 170 ParentProcessIDIsValid()171 bool ParentProcessIDIsValid() const { 172 return m_parent_pid != LLDB_INVALID_PROCESS_ID; 173 } 174 175 void Dump(Stream &s, UserIDResolver &resolver) const; 176 177 static void DumpTableHeader(Stream &s, bool show_args, bool verbose); 178 179 void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args, 180 bool verbose) const; 181 182 protected: 183 uint32_t m_euid = UINT32_MAX; 184 uint32_t m_egid = UINT32_MAX; 185 lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; 186 }; 187 188 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; 189 190 class ProcessInfoList { 191 public: ProcessInfoList(const ProcessInstanceInfoList & list)192 ProcessInfoList(const ProcessInstanceInfoList &list) : m_list(list) {} 193 GetSize()194 uint32_t GetSize() const { return m_list.size(); } 195 GetProcessInfoAtIndex(uint32_t idx,ProcessInstanceInfo & info)196 bool GetProcessInfoAtIndex(uint32_t idx, ProcessInstanceInfo &info) { 197 if (idx < m_list.size()) { 198 info = m_list[idx]; 199 return true; 200 } 201 return false; 202 } 203 Clear()204 void Clear() { return m_list.clear(); } 205 206 private: 207 ProcessInstanceInfoList m_list; 208 }; 209 210 // ProcessInstanceInfoMatch 211 // 212 // A class to help matching one ProcessInstanceInfo to another. 213 214 class ProcessInstanceInfoMatch { 215 public: 216 ProcessInstanceInfoMatch() = default; 217 ProcessInstanceInfoMatch(const char * process_name,NameMatch process_name_match_type)218 ProcessInstanceInfoMatch(const char *process_name, 219 NameMatch process_name_match_type) 220 : m_name_match_type(process_name_match_type), m_match_all_users(false) { 221 m_match_info.GetExecutableFile().SetFile(process_name, 222 FileSpec::Style::native); 223 } 224 GetProcessInfo()225 ProcessInstanceInfo &GetProcessInfo() { return m_match_info; } 226 GetProcessInfo()227 const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; } 228 GetMatchAllUsers()229 bool GetMatchAllUsers() const { return m_match_all_users; } 230 SetMatchAllUsers(bool b)231 void SetMatchAllUsers(bool b) { m_match_all_users = b; } 232 GetNameMatchType()233 NameMatch GetNameMatchType() const { return m_name_match_type; } 234 SetNameMatchType(NameMatch name_match_type)235 void SetNameMatchType(NameMatch name_match_type) { 236 m_name_match_type = name_match_type; 237 } 238 239 /// Return true iff the architecture in this object matches arch_spec. 240 bool ArchitectureMatches(const ArchSpec &arch_spec) const; 241 242 /// Return true iff the process name in this object matches process_name. 243 bool NameMatches(const char *process_name) const; 244 245 /// Return true iff the process ID and parent process IDs in this object match 246 /// the ones in proc_info. 247 bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const; 248 249 /// Return true iff the (both effective and real) user and group IDs in this 250 /// object match the ones in proc_info. 251 bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const; 252 253 bool Matches(const ProcessInstanceInfo &proc_info) const; 254 255 bool MatchAllProcesses() const; 256 void Clear(); 257 258 protected: 259 ProcessInstanceInfo m_match_info; 260 NameMatch m_name_match_type = NameMatch::Ignore; 261 bool m_match_all_users = false; 262 }; 263 264 } // namespace lldb_private 265 266 #endif // LLDB_UTILITY_PROCESSINFO_H 267