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 <optional> 19 #include <vector> 20 21 namespace lldb_private { 22 23 class UserIDResolver; 24 25 // ProcessInfo 26 // 27 // A base class for information for a process. This can be used to fill 28 // out information for a process prior to launching it, or it can be used for 29 // an instance of a process and can be filled in with the existing values for 30 // that process. 31 class ProcessInfo { 32 public: 33 ProcessInfo(); 34 35 ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid); 36 37 void Clear(); 38 39 const char *GetName() const; 40 41 llvm::StringRef GetNameAsStringRef() const; 42 GetExecutableFile()43 FileSpec &GetExecutableFile() { return m_executable; } 44 45 void SetExecutableFile(const FileSpec &exe_file, 46 bool add_exe_file_as_first_arg); 47 GetExecutableFile()48 const FileSpec &GetExecutableFile() const { return m_executable; } 49 GetUserID()50 uint32_t GetUserID() const { return m_uid; } 51 GetGroupID()52 uint32_t GetGroupID() const { return m_gid; } 53 UserIDIsValid()54 bool UserIDIsValid() const { return m_uid != UINT32_MAX; } 55 GroupIDIsValid()56 bool GroupIDIsValid() const { return m_gid != UINT32_MAX; } 57 SetUserID(uint32_t uid)58 void SetUserID(uint32_t uid) { m_uid = uid; } 59 SetGroupID(uint32_t gid)60 void SetGroupID(uint32_t gid) { m_gid = gid; } 61 GetArchitecture()62 ArchSpec &GetArchitecture() { return m_arch; } 63 GetArchitecture()64 const ArchSpec &GetArchitecture() const { return m_arch; } 65 SetArchitecture(const ArchSpec & arch)66 void SetArchitecture(const ArchSpec &arch) { m_arch = arch; } 67 GetProcessID()68 lldb::pid_t GetProcessID() const { return m_pid; } 69 SetProcessID(lldb::pid_t pid)70 void SetProcessID(lldb::pid_t pid) { m_pid = pid; } 71 ProcessIDIsValid()72 bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; } 73 74 void Dump(Stream &s, Platform *platform) const; 75 GetArguments()76 Args &GetArguments() { return m_arguments; } 77 GetArguments()78 const Args &GetArguments() const { return m_arguments; } 79 80 llvm::StringRef GetArg0() const; 81 82 void SetArg0(llvm::StringRef arg); 83 84 void SetArguments(const Args &args, bool first_arg_is_executable); 85 86 void SetArguments(char const **argv, bool first_arg_is_executable); 87 GetEnvironment()88 Environment &GetEnvironment() { return m_environment; } GetEnvironment()89 const Environment &GetEnvironment() const { return m_environment; } 90 91 bool IsScriptedProcess() const; 92 GetScriptedMetadata()93 lldb::ScriptedMetadataSP GetScriptedMetadata() const { 94 return m_scripted_metadata_sp; 95 } 96 SetScriptedMetadata(lldb::ScriptedMetadataSP metadata_sp)97 void SetScriptedMetadata(lldb::ScriptedMetadataSP metadata_sp) { 98 m_scripted_metadata_sp = metadata_sp; 99 } 100 101 // Get and set the actual listener that will be used for the process events GetListener()102 lldb::ListenerSP GetListener() const { return m_listener_sp; } 103 SetListener(const lldb::ListenerSP & listener_sp)104 void SetListener(const lldb::ListenerSP &listener_sp) { 105 m_listener_sp = listener_sp; 106 } 107 GetHijackListener()108 lldb::ListenerSP GetHijackListener() const { return m_hijack_listener_sp; } 109 SetHijackListener(const lldb::ListenerSP & listener_sp)110 void SetHijackListener(const lldb::ListenerSP &listener_sp) { 111 m_hijack_listener_sp = listener_sp; 112 } 113 GetShadowListener()114 lldb::ListenerSP GetShadowListener() const { return m_shadow_listener_sp; } 115 SetShadowListener(const lldb::ListenerSP & listener_sp)116 void SetShadowListener(const lldb::ListenerSP &listener_sp) { 117 m_shadow_listener_sp = listener_sp; 118 } 119 120 protected: 121 FileSpec m_executable; 122 std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. 123 // Not all process plug-ins support specifying an argv[0] that differs from 124 // the resolved platform executable (which is in m_executable) 125 Args m_arguments; // All program arguments except argv[0] 126 Environment m_environment; 127 uint32_t m_uid = UINT32_MAX; 128 uint32_t m_gid = UINT32_MAX; 129 ArchSpec m_arch; 130 lldb::pid_t m_pid = LLDB_INVALID_PROCESS_ID; 131 lldb::ScriptedMetadataSP m_scripted_metadata_sp = nullptr; 132 lldb::ListenerSP m_listener_sp = nullptr; 133 lldb::ListenerSP m_hijack_listener_sp = nullptr; 134 lldb::ListenerSP m_shadow_listener_sp = nullptr; 135 }; 136 137 // ProcessInstanceInfo 138 // 139 // Describes an existing process and any discoverable information that pertains 140 // to that process. 141 class ProcessInstanceInfo : public ProcessInfo { 142 public: 143 struct timespec { 144 time_t tv_sec = 0; 145 long int tv_usec = 0; 146 }; 147 148 ProcessInstanceInfo() = default; 149 ProcessInstanceInfo(const char * name,const ArchSpec & arch,lldb::pid_t pid)150 ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) 151 : ProcessInfo(name, arch, pid) {} 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 GetPriorityValue()240 std::optional<int8_t> GetPriorityValue() const { return m_priority_value; } 241 SetPriorityValue(int8_t priority_value)242 void SetPriorityValue(int8_t priority_value) { 243 m_priority_value = priority_value; 244 } 245 SetIsZombie(bool is_zombie)246 void SetIsZombie(bool is_zombie) { m_zombie = is_zombie; } 247 IsZombie()248 std::optional<bool> IsZombie() const { return m_zombie; } 249 250 void Dump(Stream &s, UserIDResolver &resolver) const; 251 252 static void DumpTableHeader(Stream &s, bool show_args, bool verbose); 253 254 void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args, 255 bool verbose) const; 256 257 protected: 258 uint32_t m_euid = UINT32_MAX; 259 uint32_t m_egid = UINT32_MAX; 260 lldb::pid_t m_parent_pid = LLDB_INVALID_PROCESS_ID; 261 lldb::pid_t m_process_group_id = LLDB_INVALID_PROCESS_ID; 262 lldb::pid_t m_process_session_id = LLDB_INVALID_PROCESS_ID; 263 struct timespec m_user_time; 264 struct timespec m_system_time; 265 struct timespec m_cumulative_user_time; 266 struct timespec m_cumulative_system_time; 267 std::optional<int8_t> m_priority_value = std::nullopt; 268 std::optional<bool> m_zombie = std::nullopt; 269 }; 270 271 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; 272 273 class ProcessInfoList { 274 public: ProcessInfoList(const ProcessInstanceInfoList & list)275 ProcessInfoList(const ProcessInstanceInfoList &list) : m_list(list) {} 276 GetSize()277 uint32_t GetSize() const { return m_list.size(); } 278 GetProcessInfoAtIndex(uint32_t idx,ProcessInstanceInfo & info)279 bool GetProcessInfoAtIndex(uint32_t idx, ProcessInstanceInfo &info) { 280 if (idx < m_list.size()) { 281 info = m_list[idx]; 282 return true; 283 } 284 return false; 285 } 286 Clear()287 void Clear() { return m_list.clear(); } 288 289 private: 290 ProcessInstanceInfoList m_list; 291 }; 292 293 // ProcessInstanceInfoMatch 294 // 295 // A class to help matching one ProcessInstanceInfo to another. 296 297 class ProcessInstanceInfoMatch { 298 public: 299 ProcessInstanceInfoMatch() = default; 300 ProcessInstanceInfoMatch(const char * process_name,NameMatch process_name_match_type)301 ProcessInstanceInfoMatch(const char *process_name, 302 NameMatch process_name_match_type) 303 : m_name_match_type(process_name_match_type), m_match_all_users(false) { 304 m_match_info.GetExecutableFile().SetFile(process_name, 305 FileSpec::Style::native); 306 } 307 GetProcessInfo()308 ProcessInstanceInfo &GetProcessInfo() { return m_match_info; } 309 GetProcessInfo()310 const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; } 311 GetMatchAllUsers()312 bool GetMatchAllUsers() const { return m_match_all_users; } 313 SetMatchAllUsers(bool b)314 void SetMatchAllUsers(bool b) { m_match_all_users = b; } 315 GetNameMatchType()316 NameMatch GetNameMatchType() const { return m_name_match_type; } 317 SetNameMatchType(NameMatch name_match_type)318 void SetNameMatchType(NameMatch name_match_type) { 319 m_name_match_type = name_match_type; 320 } 321 322 /// Return true iff the architecture in this object matches arch_spec. 323 bool ArchitectureMatches(const ArchSpec &arch_spec) const; 324 325 /// Return true iff the process name in this object matches process_name. 326 bool NameMatches(const char *process_name) const; 327 328 /// Return true iff the process ID and parent process IDs in this object match 329 /// the ones in proc_info. 330 bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const; 331 332 /// Return true iff the (both effective and real) user and group IDs in this 333 /// object match the ones in proc_info. 334 bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const; 335 336 bool Matches(const ProcessInstanceInfo &proc_info) const; 337 338 bool MatchAllProcesses() const; 339 void Clear(); 340 341 protected: 342 ProcessInstanceInfo m_match_info; 343 NameMatch m_name_match_type = NameMatch::Ignore; 344 bool m_match_all_users = false; 345 }; 346 347 } // namespace lldb_private 348 349 #endif // LLDB_UTILITY_PROCESSINFO_H 350