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 struct timespec { 143 time_t tv_sec = 0; 144 long int tv_usec = 0; 145 }; 146 147 ProcessInstanceInfo() = default; 148 ProcessInstanceInfo(const char * name,const ArchSpec & arch,lldb::pid_t pid)149 ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) 150 : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), 151 m_parent_pid(LLDB_INVALID_PROCESS_ID) {} 152 Clear()153 void Clear() { 154 ProcessInfo::Clear(); 155 m_euid = UINT32_MAX; 156 m_egid = UINT32_MAX; 157 m_parent_pid = LLDB_INVALID_PROCESS_ID; 158 } 159 GetEffectiveUserID()160 uint32_t GetEffectiveUserID() const { return m_euid; } 161 GetEffectiveGroupID()162 uint32_t GetEffectiveGroupID() const { return m_egid; } 163 EffectiveUserIDIsValid()164 bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; } 165 EffectiveGroupIDIsValid()166 bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; } 167 SetEffectiveUserID(uint32_t uid)168 void SetEffectiveUserID(uint32_t uid) { m_euid = uid; } 169 SetEffectiveGroupID(uint32_t gid)170 void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; } 171 GetParentProcessID()172 lldb::pid_t GetParentProcessID() const { return m_parent_pid; } 173 SetParentProcessID(lldb::pid_t pid)174 void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } 175 ParentProcessIDIsValid()176 bool ParentProcessIDIsValid() const { 177 return m_parent_pid != LLDB_INVALID_PROCESS_ID; 178 } 179 GetProcessGroupID()180 lldb::pid_t GetProcessGroupID() const { return m_process_group_id; } 181 SetProcessGroupID(lldb::pid_t pgrp)182 void SetProcessGroupID(lldb::pid_t pgrp) { m_process_group_id = pgrp; } 183 ProcessGroupIDIsValid()184 bool ProcessGroupIDIsValid() const { 185 return m_process_group_id != LLDB_INVALID_PROCESS_ID; 186 } 187 GetProcessSessionID()188 lldb::pid_t GetProcessSessionID() const { return m_process_session_id; } 189 SetProcessSessionID(lldb::pid_t session)190 void SetProcessSessionID(lldb::pid_t session) { 191 m_process_session_id = session; 192 } 193 ProcessSessionIDIsValid()194 bool ProcessSessionIDIsValid() const { 195 return m_process_session_id != LLDB_INVALID_PROCESS_ID; 196 } 197 GetUserTime()198 struct timespec GetUserTime() const { return m_user_time; } 199 SetUserTime(struct timespec utime)200 void SetUserTime(struct timespec utime) { m_user_time = utime; } 201 UserTimeIsValid()202 bool UserTimeIsValid() const { 203 return m_user_time.tv_sec > 0 || m_user_time.tv_usec > 0; 204 } 205 GetSystemTime()206 struct timespec GetSystemTime() const { return m_system_time; } 207 SetSystemTime(struct timespec stime)208 void SetSystemTime(struct timespec stime) { m_system_time = stime; } 209 SystemTimeIsValid()210 bool SystemTimeIsValid() const { 211 return m_system_time.tv_sec > 0 || m_system_time.tv_usec > 0; 212 } 213 GetCumulativeUserTime()214 struct timespec GetCumulativeUserTime() const { 215 return m_cumulative_user_time; 216 } 217 SetCumulativeUserTime(struct timespec cutime)218 void SetCumulativeUserTime(struct timespec cutime) { 219 m_cumulative_user_time = cutime; 220 } 221 CumulativeUserTimeIsValid()222 bool CumulativeUserTimeIsValid() const { 223 return m_cumulative_user_time.tv_sec > 0 || 224 m_cumulative_user_time.tv_usec > 0; 225 } 226 GetCumulativeSystemTime()227 struct timespec GetCumulativeSystemTime() const { 228 return m_cumulative_system_time; 229 } 230 SetCumulativeSystemTime(struct timespec cstime)231 void SetCumulativeSystemTime(struct timespec cstime) { 232 m_cumulative_system_time = cstime; 233 } 234 CumulativeSystemTimeIsValid()235 bool CumulativeSystemTimeIsValid() const { 236 return m_cumulative_system_time.tv_sec > 0 || 237 m_cumulative_system_time.tv_usec > 0; 238 } 239 240 void Dump(Stream &s, UserIDResolver &resolver) const; 241 242 static void DumpTableHeader(Stream &s, bool show_args, bool verbose); 243 244 void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args, 245 bool verbose) const; 246 247 protected: 248 uint32_t m_euid = UINT32_MAX; 249 uint32_t m_egid = UINT32_MAX; 250 lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; 251 lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; 252 lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; 253 struct timespec m_user_time {}; 254 struct timespec m_system_time {}; 255 struct timespec m_cumulative_user_time {}; 256 struct timespec m_cumulative_system_time {}; 257 }; 258 259 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; 260 261 class ProcessInfoList { 262 public: ProcessInfoList(const ProcessInstanceInfoList & list)263 ProcessInfoList(const ProcessInstanceInfoList &list) : m_list(list) {} 264 GetSize()265 uint32_t GetSize() const { return m_list.size(); } 266 GetProcessInfoAtIndex(uint32_t idx,ProcessInstanceInfo & info)267 bool GetProcessInfoAtIndex(uint32_t idx, ProcessInstanceInfo &info) { 268 if (idx < m_list.size()) { 269 info = m_list[idx]; 270 return true; 271 } 272 return false; 273 } 274 Clear()275 void Clear() { return m_list.clear(); } 276 277 private: 278 ProcessInstanceInfoList m_list; 279 }; 280 281 // ProcessInstanceInfoMatch 282 // 283 // A class to help matching one ProcessInstanceInfo to another. 284 285 class ProcessInstanceInfoMatch { 286 public: 287 ProcessInstanceInfoMatch() = default; 288 ProcessInstanceInfoMatch(const char * process_name,NameMatch process_name_match_type)289 ProcessInstanceInfoMatch(const char *process_name, 290 NameMatch process_name_match_type) 291 : m_name_match_type(process_name_match_type), m_match_all_users(false) { 292 m_match_info.GetExecutableFile().SetFile(process_name, 293 FileSpec::Style::native); 294 } 295 GetProcessInfo()296 ProcessInstanceInfo &GetProcessInfo() { return m_match_info; } 297 GetProcessInfo()298 const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; } 299 GetMatchAllUsers()300 bool GetMatchAllUsers() const { return m_match_all_users; } 301 SetMatchAllUsers(bool b)302 void SetMatchAllUsers(bool b) { m_match_all_users = b; } 303 GetNameMatchType()304 NameMatch GetNameMatchType() const { return m_name_match_type; } 305 SetNameMatchType(NameMatch name_match_type)306 void SetNameMatchType(NameMatch name_match_type) { 307 m_name_match_type = name_match_type; 308 } 309 310 /// Return true iff the architecture in this object matches arch_spec. 311 bool ArchitectureMatches(const ArchSpec &arch_spec) const; 312 313 /// Return true iff the process name in this object matches process_name. 314 bool NameMatches(const char *process_name) const; 315 316 /// Return true iff the process ID and parent process IDs in this object match 317 /// the ones in proc_info. 318 bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const; 319 320 /// Return true iff the (both effective and real) user and group IDs in this 321 /// object match the ones in proc_info. 322 bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const; 323 324 bool Matches(const ProcessInstanceInfo &proc_info) const; 325 326 bool MatchAllProcesses() const; 327 void Clear(); 328 329 protected: 330 ProcessInstanceInfo m_match_info; 331 NameMatch m_name_match_type = NameMatch::Ignore; 332 bool m_match_all_users = false; 333 }; 334 335 } // namespace lldb_private 336 337 #endif // LLDB_UTILITY_PROCESSINFO_H 338