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/Reproducer.h" 18 #include "llvm/Support/YAMLTraits.h" 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 43 FileSpec &GetExecutableFile() { return m_executable; } 44 45 void SetExecutableFile(const FileSpec &exe_file, 46 bool add_exe_file_as_first_arg); 47 48 const FileSpec &GetExecutableFile() const { return m_executable; } 49 50 uint32_t GetUserID() const { return m_uid; } 51 52 uint32_t GetGroupID() const { return m_gid; } 53 54 bool UserIDIsValid() const { return m_uid != UINT32_MAX; } 55 56 bool GroupIDIsValid() const { return m_gid != UINT32_MAX; } 57 58 void SetUserID(uint32_t uid) { m_uid = uid; } 59 60 void SetGroupID(uint32_t gid) { m_gid = gid; } 61 62 ArchSpec &GetArchitecture() { return m_arch; } 63 64 const ArchSpec &GetArchitecture() const { return m_arch; } 65 66 void SetArchitecture(const ArchSpec &arch) { m_arch = arch; } 67 68 lldb::pid_t GetProcessID() const { return m_pid; } 69 70 void SetProcessID(lldb::pid_t pid) { m_pid = pid; } 71 72 bool ProcessIDIsValid() const { return m_pid != LLDB_INVALID_PROCESS_ID; } 73 74 void Dump(Stream &s, Platform *platform) const; 75 76 Args &GetArguments() { return m_arguments; } 77 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 88 Environment &GetEnvironment() { return m_environment; } 89 const Environment &GetEnvironment() const { return m_environment; } 90 91 protected: 92 template <class T> friend struct llvm::yaml::MappingTraits; 93 FileSpec m_executable; 94 std::string m_arg0; // argv[0] if supported. If empty, then use m_executable. 95 // Not all process plug-ins support specifying an argv[0] that differs from 96 // the resolved platform executable (which is in m_executable) 97 Args m_arguments; // All program arguments except argv[0] 98 Environment m_environment; 99 uint32_t m_uid; 100 uint32_t m_gid; 101 ArchSpec m_arch; 102 lldb::pid_t m_pid; 103 }; 104 105 // ProcessInstanceInfo 106 // 107 // Describes an existing process and any discoverable information that pertains 108 // to that process. 109 class ProcessInstanceInfo : public ProcessInfo { 110 public: 111 ProcessInstanceInfo() 112 : ProcessInfo(), m_euid(UINT32_MAX), m_egid(UINT32_MAX), 113 m_parent_pid(LLDB_INVALID_PROCESS_ID) {} 114 115 ProcessInstanceInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) 116 : ProcessInfo(name, arch, pid), m_euid(UINT32_MAX), m_egid(UINT32_MAX), 117 m_parent_pid(LLDB_INVALID_PROCESS_ID) {} 118 119 void Clear() { 120 ProcessInfo::Clear(); 121 m_euid = UINT32_MAX; 122 m_egid = UINT32_MAX; 123 m_parent_pid = LLDB_INVALID_PROCESS_ID; 124 } 125 126 uint32_t GetEffectiveUserID() const { return m_euid; } 127 128 uint32_t GetEffectiveGroupID() const { return m_egid; } 129 130 bool EffectiveUserIDIsValid() const { return m_euid != UINT32_MAX; } 131 132 bool EffectiveGroupIDIsValid() const { return m_egid != UINT32_MAX; } 133 134 void SetEffectiveUserID(uint32_t uid) { m_euid = uid; } 135 136 void SetEffectiveGroupID(uint32_t gid) { m_egid = gid; } 137 138 lldb::pid_t GetParentProcessID() const { return m_parent_pid; } 139 140 void SetParentProcessID(lldb::pid_t pid) { m_parent_pid = pid; } 141 142 bool ParentProcessIDIsValid() const { 143 return m_parent_pid != LLDB_INVALID_PROCESS_ID; 144 } 145 146 void Dump(Stream &s, UserIDResolver &resolver) const; 147 148 static void DumpTableHeader(Stream &s, bool show_args, bool verbose); 149 150 void DumpAsTableRow(Stream &s, UserIDResolver &resolver, bool show_args, 151 bool verbose) const; 152 153 protected: 154 friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>; 155 uint32_t m_euid; 156 uint32_t m_egid; 157 lldb::pid_t m_parent_pid; 158 }; 159 160 typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList; 161 162 // ProcessInstanceInfoMatch 163 // 164 // A class to help matching one ProcessInstanceInfo to another. 165 166 class ProcessInstanceInfoMatch { 167 public: 168 ProcessInstanceInfoMatch() 169 : m_match_info(), m_name_match_type(NameMatch::Ignore), 170 m_match_all_users(false) {} 171 172 ProcessInstanceInfoMatch(const char *process_name, 173 NameMatch process_name_match_type) 174 : m_match_info(), m_name_match_type(process_name_match_type), 175 m_match_all_users(false) { 176 m_match_info.GetExecutableFile().SetFile(process_name, 177 FileSpec::Style::native); 178 } 179 180 ProcessInstanceInfo &GetProcessInfo() { return m_match_info; } 181 182 const ProcessInstanceInfo &GetProcessInfo() const { return m_match_info; } 183 184 bool GetMatchAllUsers() const { return m_match_all_users; } 185 186 void SetMatchAllUsers(bool b) { m_match_all_users = b; } 187 188 NameMatch GetNameMatchType() const { return m_name_match_type; } 189 190 void SetNameMatchType(NameMatch name_match_type) { 191 m_name_match_type = name_match_type; 192 } 193 194 /// Return true iff the architecture in this object matches arch_spec. 195 bool ArchitectureMatches(const ArchSpec &arch_spec) const; 196 197 /// Return true iff the process name in this object matches process_name. 198 bool NameMatches(const char *process_name) const; 199 200 /// Return true iff the process ID and parent process IDs in this object match 201 /// the ones in proc_info. 202 bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const; 203 204 /// Return true iff the (both effective and real) user and group IDs in this 205 /// object match the ones in proc_info. 206 bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const; 207 208 bool Matches(const ProcessInstanceInfo &proc_info) const; 209 210 bool MatchAllProcesses() const; 211 void Clear(); 212 213 protected: 214 ProcessInstanceInfo m_match_info; 215 NameMatch m_name_match_type; 216 bool m_match_all_users; 217 }; 218 219 namespace repro { 220 class ProcessInfoRecorder : public AbstractRecorder { 221 public: 222 ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec) 223 : AbstractRecorder(filename, ec) {} 224 225 static llvm::Expected<std::unique_ptr<ProcessInfoRecorder>> 226 Create(const FileSpec &filename); 227 228 void Record(const ProcessInstanceInfoList &process_infos); 229 }; 230 231 class ProcessInfoProvider : public repro::Provider<ProcessInfoProvider> { 232 public: 233 struct Info { 234 static const char *name; 235 static const char *file; 236 }; 237 238 ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {} 239 240 ProcessInfoRecorder *GetNewProcessInfoRecorder(); 241 242 void Keep() override; 243 void Discard() override; 244 245 static char ID; 246 247 private: 248 std::unique_ptr<llvm::raw_fd_ostream> m_stream_up; 249 std::vector<std::unique_ptr<ProcessInfoRecorder>> m_process_info_recorders; 250 }; 251 252 llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList(); 253 254 } // namespace repro 255 } // namespace lldb_private 256 257 LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ProcessInstanceInfo) 258 259 namespace llvm { 260 namespace yaml { 261 template <> struct MappingTraits<lldb_private::ProcessInstanceInfo> { 262 static void mapping(IO &io, lldb_private::ProcessInstanceInfo &PII); 263 }; 264 } // namespace yaml 265 } // namespace llvm 266 267 #endif // LLDB_UTILITY_PROCESSINFO_H 268