180814287SRaphael Isemann //===-- ProcessInfo.cpp ---------------------------------------------------===//
2805e7106SZachary Turner //
3805e7106SZachary Turner // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4805e7106SZachary Turner // See https://llvm.org/LICENSE.txt for license information.
5805e7106SZachary Turner // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6805e7106SZachary Turner //
7805e7106SZachary Turner //===----------------------------------------------------------------------===//
8805e7106SZachary Turner
9805e7106SZachary Turner #include "lldb/Utility/ProcessInfo.h"
10805e7106SZachary Turner
11805e7106SZachary Turner #include "lldb/Utility/ArchSpec.h"
12bb894b97SJonas Devlieghere #include "lldb/Utility/ReproducerProvider.h"
13805e7106SZachary Turner #include "lldb/Utility/Stream.h"
14805e7106SZachary Turner #include "lldb/Utility/StreamString.h"
15805e7106SZachary Turner #include "lldb/Utility/UserIDResolver.h"
16805e7106SZachary Turner #include "llvm/ADT/SmallString.h"
17805e7106SZachary Turner
18805e7106SZachary Turner #include <climits>
19805e7106SZachary Turner
20805e7106SZachary Turner using namespace lldb;
21805e7106SZachary Turner using namespace lldb_private;
222451cbf0SJonas Devlieghere using namespace lldb_private::repro;
23805e7106SZachary Turner
ProcessInfo()24805e7106SZachary Turner ProcessInfo::ProcessInfo()
259494c510SJonas Devlieghere : m_executable(), m_arguments(), m_environment(), m_arch() {}
26805e7106SZachary Turner
ProcessInfo(const char * name,const ArchSpec & arch,lldb::pid_t pid)27805e7106SZachary Turner ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,
28805e7106SZachary Turner lldb::pid_t pid)
2928c878aeSShafik Yaghmour : m_executable(name), m_arguments(), m_environment(), m_arch(arch),
3028c878aeSShafik Yaghmour m_pid(pid) {}
31805e7106SZachary Turner
Clear()32805e7106SZachary Turner void ProcessInfo::Clear() {
33805e7106SZachary Turner m_executable.Clear();
34805e7106SZachary Turner m_arguments.Clear();
35805e7106SZachary Turner m_environment.clear();
36805e7106SZachary Turner m_uid = UINT32_MAX;
37805e7106SZachary Turner m_gid = UINT32_MAX;
38805e7106SZachary Turner m_arch.Clear();
39805e7106SZachary Turner m_pid = LLDB_INVALID_PROCESS_ID;
40805e7106SZachary Turner }
41805e7106SZachary Turner
GetName() const42805e7106SZachary Turner const char *ProcessInfo::GetName() const {
43805e7106SZachary Turner return m_executable.GetFilename().GetCString();
44805e7106SZachary Turner }
45805e7106SZachary Turner
GetNameAsStringRef() const4672ca5f36SRaphael Isemann llvm::StringRef ProcessInfo::GetNameAsStringRef() const {
4772ca5f36SRaphael Isemann return m_executable.GetFilename().GetStringRef();
48805e7106SZachary Turner }
49805e7106SZachary Turner
Dump(Stream & s,Platform * platform) const50805e7106SZachary Turner void ProcessInfo::Dump(Stream &s, Platform *platform) const {
51805e7106SZachary Turner s << "Executable: " << GetName() << "\n";
52805e7106SZachary Turner s << "Triple: ";
532f1e7b3dSRaphael Isemann m_arch.DumpTriple(s.AsRawOstream());
54805e7106SZachary Turner s << "\n";
55805e7106SZachary Turner
56805e7106SZachary Turner s << "Arguments:\n";
57805e7106SZachary Turner m_arguments.Dump(s);
58805e7106SZachary Turner
59805e7106SZachary Turner s.Format("Environment:\n{0}", m_environment);
60805e7106SZachary Turner }
61805e7106SZachary Turner
SetExecutableFile(const FileSpec & exe_file,bool add_exe_file_as_first_arg)62805e7106SZachary Turner void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,
63805e7106SZachary Turner bool add_exe_file_as_first_arg) {
64805e7106SZachary Turner if (exe_file) {
65805e7106SZachary Turner m_executable = exe_file;
66805e7106SZachary Turner if (add_exe_file_as_first_arg) {
67805e7106SZachary Turner llvm::SmallString<128> filename;
68805e7106SZachary Turner exe_file.GetPath(filename);
69805e7106SZachary Turner if (!filename.empty())
70805e7106SZachary Turner m_arguments.InsertArgumentAtIndex(0, filename);
71805e7106SZachary Turner }
72805e7106SZachary Turner } else {
73805e7106SZachary Turner m_executable.Clear();
74805e7106SZachary Turner }
75805e7106SZachary Turner }
76805e7106SZachary Turner
GetArg0() const77805e7106SZachary Turner llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; }
78805e7106SZachary Turner
SetArg0(llvm::StringRef arg)79adcd0268SBenjamin Kramer void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); }
80805e7106SZachary Turner
SetArguments(char const ** argv,bool first_arg_is_executable)81805e7106SZachary Turner void ProcessInfo::SetArguments(char const **argv,
82805e7106SZachary Turner bool first_arg_is_executable) {
83805e7106SZachary Turner m_arguments.SetArguments(argv);
84805e7106SZachary Turner
85805e7106SZachary Turner // Is the first argument the executable?
86805e7106SZachary Turner if (first_arg_is_executable) {
87805e7106SZachary Turner const char *first_arg = m_arguments.GetArgumentAtIndex(0);
88805e7106SZachary Turner if (first_arg) {
89805e7106SZachary Turner // Yes the first argument is an executable, set it as the executable in
90805e7106SZachary Turner // the launch options. Don't resolve the file path as the path could be a
91805e7106SZachary Turner // remote platform path
92805e7106SZachary Turner m_executable.SetFile(first_arg, FileSpec::Style::native);
93805e7106SZachary Turner }
94805e7106SZachary Turner }
95805e7106SZachary Turner }
96805e7106SZachary Turner
SetArguments(const Args & args,bool first_arg_is_executable)97805e7106SZachary Turner void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) {
98805e7106SZachary Turner // Copy all arguments
99805e7106SZachary Turner m_arguments = args;
100805e7106SZachary Turner
101805e7106SZachary Turner // Is the first argument the executable?
102805e7106SZachary Turner if (first_arg_is_executable) {
103805e7106SZachary Turner const char *first_arg = m_arguments.GetArgumentAtIndex(0);
104805e7106SZachary Turner if (first_arg) {
105805e7106SZachary Turner // Yes the first argument is an executable, set it as the executable in
106805e7106SZachary Turner // the launch options. Don't resolve the file path as the path could be a
107805e7106SZachary Turner // remote platform path
108805e7106SZachary Turner m_executable.SetFile(first_arg, FileSpec::Style::native);
109805e7106SZachary Turner }
110805e7106SZachary Turner }
111805e7106SZachary Turner }
112805e7106SZachary Turner
Dump(Stream & s,UserIDResolver & resolver) const113805e7106SZachary Turner void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const {
114805e7106SZachary Turner if (m_pid != LLDB_INVALID_PROCESS_ID)
115805e7106SZachary Turner s.Printf(" pid = %" PRIu64 "\n", m_pid);
116805e7106SZachary Turner
117805e7106SZachary Turner if (m_parent_pid != LLDB_INVALID_PROCESS_ID)
118805e7106SZachary Turner s.Printf(" parent = %" PRIu64 "\n", m_parent_pid);
119805e7106SZachary Turner
120805e7106SZachary Turner if (m_executable) {
121805e7106SZachary Turner s.Printf(" name = %s\n", m_executable.GetFilename().GetCString());
122805e7106SZachary Turner s.PutCString(" file = ");
1234dac97ebSRaphael Isemann m_executable.Dump(s.AsRawOstream());
124805e7106SZachary Turner s.EOL();
125805e7106SZachary Turner }
126805e7106SZachary Turner const uint32_t argc = m_arguments.GetArgumentCount();
127805e7106SZachary Turner if (argc > 0) {
128805e7106SZachary Turner for (uint32_t i = 0; i < argc; i++) {
129805e7106SZachary Turner const char *arg = m_arguments.GetArgumentAtIndex(i);
130805e7106SZachary Turner if (i < 10)
131805e7106SZachary Turner s.Printf(" arg[%u] = %s\n", i, arg);
132805e7106SZachary Turner else
133805e7106SZachary Turner s.Printf("arg[%u] = %s\n", i, arg);
134805e7106SZachary Turner }
135805e7106SZachary Turner }
136805e7106SZachary Turner
137805e7106SZachary Turner s.Format("{0}", m_environment);
138805e7106SZachary Turner
139805e7106SZachary Turner if (m_arch.IsValid()) {
140805e7106SZachary Turner s.Printf(" arch = ");
1412f1e7b3dSRaphael Isemann m_arch.DumpTriple(s.AsRawOstream());
142805e7106SZachary Turner s.EOL();
143805e7106SZachary Turner }
144805e7106SZachary Turner
145805e7106SZachary Turner if (UserIDIsValid()) {
146805e7106SZachary Turner s.Format(" uid = {0,-5} ({1})\n", GetUserID(),
147*aa88161bSKazu Hirata resolver.GetUserName(GetUserID()).value_or(""));
148805e7106SZachary Turner }
149805e7106SZachary Turner if (GroupIDIsValid()) {
150805e7106SZachary Turner s.Format(" gid = {0,-5} ({1})\n", GetGroupID(),
151*aa88161bSKazu Hirata resolver.GetGroupName(GetGroupID()).value_or(""));
152805e7106SZachary Turner }
153805e7106SZachary Turner if (EffectiveUserIDIsValid()) {
154805e7106SZachary Turner s.Format(" euid = {0,-5} ({1})\n", GetEffectiveUserID(),
155*aa88161bSKazu Hirata resolver.GetUserName(GetEffectiveUserID()).value_or(""));
156805e7106SZachary Turner }
157805e7106SZachary Turner if (EffectiveGroupIDIsValid()) {
158805e7106SZachary Turner s.Format(" egid = {0,-5} ({1})\n", GetEffectiveGroupID(),
159*aa88161bSKazu Hirata resolver.GetGroupName(GetEffectiveGroupID()).value_or(""));
160805e7106SZachary Turner }
161805e7106SZachary Turner }
162805e7106SZachary Turner
DumpTableHeader(Stream & s,bool show_args,bool verbose)163805e7106SZachary Turner void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,
164805e7106SZachary Turner bool verbose) {
165805e7106SZachary Turner const char *label;
166805e7106SZachary Turner if (show_args || verbose)
167805e7106SZachary Turner label = "ARGUMENTS";
168805e7106SZachary Turner else
169805e7106SZachary Turner label = "NAME";
170805e7106SZachary Turner
171805e7106SZachary Turner if (verbose) {
172805e7106SZachary Turner s.Printf("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE "
173805e7106SZachary Turner " %s\n",
174805e7106SZachary Turner label);
175e0a398bfSWalter Erquinigo s.PutCString(
176e0a398bfSWalter Erquinigo "====== ====== ========== ========== ========== ========== "
177e0a398bfSWalter Erquinigo "============================== ============================\n");
178805e7106SZachary Turner } else {
179e0a398bfSWalter Erquinigo s.Printf("PID PARENT USER TRIPLE %s\n",
180e0a398bfSWalter Erquinigo label);
181e0a398bfSWalter Erquinigo s.PutCString("====== ====== ========== ============================== "
182805e7106SZachary Turner "============================\n");
183805e7106SZachary Turner }
184805e7106SZachary Turner }
185805e7106SZachary Turner
DumpAsTableRow(Stream & s,UserIDResolver & resolver,bool show_args,bool verbose) const186805e7106SZachary Turner void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
187805e7106SZachary Turner bool show_args, bool verbose) const {
188805e7106SZachary Turner if (m_pid != LLDB_INVALID_PROCESS_ID) {
189805e7106SZachary Turner s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
190805e7106SZachary Turner
191805e7106SZachary Turner StreamString arch_strm;
192805e7106SZachary Turner if (m_arch.IsValid())
1932f1e7b3dSRaphael Isemann m_arch.DumpTriple(arch_strm.AsRawOstream());
194805e7106SZachary Turner
195602f29fdSPavel Labath auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,
196602f29fdSPavel Labath uint32_t (ProcessInstanceInfo::*getID)() const,
197602f29fdSPavel Labath llvm::Optional<llvm::StringRef> (UserIDResolver::*getName)(
198805e7106SZachary Turner UserIDResolver::id_t id)) {
199602f29fdSPavel Labath const char *format = "{0,-10} ";
200602f29fdSPavel Labath if (!(this->*isValid)()) {
201602f29fdSPavel Labath s.Format(format, "");
202602f29fdSPavel Labath return;
203602f29fdSPavel Labath }
204602f29fdSPavel Labath uint32_t id = (this->*getID)();
205602f29fdSPavel Labath if (auto name = (resolver.*getName)(id))
206602f29fdSPavel Labath s.Format(format, *name);
207805e7106SZachary Turner else
208602f29fdSPavel Labath s.Format(format, id);
209805e7106SZachary Turner };
210805e7106SZachary Turner if (verbose) {
211602f29fdSPavel Labath print(&ProcessInstanceInfo::UserIDIsValid,
212602f29fdSPavel Labath &ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);
213602f29fdSPavel Labath print(&ProcessInstanceInfo::GroupIDIsValid,
214602f29fdSPavel Labath &ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);
215602f29fdSPavel Labath print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
216602f29fdSPavel Labath &ProcessInstanceInfo::GetEffectiveUserID,
217602f29fdSPavel Labath &UserIDResolver::GetUserName);
218602f29fdSPavel Labath print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,
219602f29fdSPavel Labath &ProcessInstanceInfo::GetEffectiveGroupID,
220602f29fdSPavel Labath &UserIDResolver::GetGroupName);
221805e7106SZachary Turner
222e0a398bfSWalter Erquinigo s.Printf("%-30s ", arch_strm.GetData());
223805e7106SZachary Turner } else {
224602f29fdSPavel Labath print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
225602f29fdSPavel Labath &ProcessInstanceInfo::GetEffectiveUserID,
226602f29fdSPavel Labath &UserIDResolver::GetUserName);
227e0a398bfSWalter Erquinigo s.Printf("%-30s ", arch_strm.GetData());
228805e7106SZachary Turner }
229805e7106SZachary Turner
230805e7106SZachary Turner if (verbose || show_args) {
23148a50ee0SWalter Erquinigo s.PutCString(m_arg0);
232805e7106SZachary Turner const uint32_t argc = m_arguments.GetArgumentCount();
233805e7106SZachary Turner for (uint32_t i = 0; i < argc; i++) {
234805e7106SZachary Turner s.PutChar(' ');
235805e7106SZachary Turner s.PutCString(m_arguments.GetArgumentAtIndex(i));
236805e7106SZachary Turner }
237805e7106SZachary Turner } else {
238805e7106SZachary Turner s.PutCString(GetName());
239805e7106SZachary Turner }
240805e7106SZachary Turner
241805e7106SZachary Turner s.EOL();
242805e7106SZachary Turner }
243805e7106SZachary Turner }
244805e7106SZachary Turner
ArchitectureMatches(const ArchSpec & arch_spec) const245a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::ArchitectureMatches(
246a8b18baaSPavel Labath const ArchSpec &arch_spec) const {
247a8b18baaSPavel Labath return !m_match_info.GetArchitecture().IsValid() ||
248a8b18baaSPavel Labath m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);
249a8b18baaSPavel Labath }
250a8b18baaSPavel Labath
NameMatches(const char * process_name) const251805e7106SZachary Turner bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
252a8b18baaSPavel Labath if (m_name_match_type == NameMatch::Ignore)
253805e7106SZachary Turner return true;
254805e7106SZachary Turner const char *match_name = m_match_info.GetName();
255805e7106SZachary Turner if (!match_name)
256805e7106SZachary Turner return true;
257805e7106SZachary Turner
258805e7106SZachary Turner return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
259805e7106SZachary Turner }
260805e7106SZachary Turner
ProcessIDsMatch(const ProcessInstanceInfo & proc_info) const261a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::ProcessIDsMatch(
262805e7106SZachary Turner const ProcessInstanceInfo &proc_info) const {
263805e7106SZachary Turner if (m_match_info.ProcessIDIsValid() &&
264805e7106SZachary Turner m_match_info.GetProcessID() != proc_info.GetProcessID())
265805e7106SZachary Turner return false;
266805e7106SZachary Turner
267805e7106SZachary Turner if (m_match_info.ParentProcessIDIsValid() &&
268805e7106SZachary Turner m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
269805e7106SZachary Turner return false;
270a8b18baaSPavel Labath return true;
271a8b18baaSPavel Labath }
272805e7106SZachary Turner
UserIDsMatch(const ProcessInstanceInfo & proc_info) const273a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::UserIDsMatch(
274a8b18baaSPavel Labath const ProcessInstanceInfo &proc_info) const {
275805e7106SZachary Turner if (m_match_info.UserIDIsValid() &&
276805e7106SZachary Turner m_match_info.GetUserID() != proc_info.GetUserID())
277805e7106SZachary Turner return false;
278805e7106SZachary Turner
279805e7106SZachary Turner if (m_match_info.GroupIDIsValid() &&
280805e7106SZachary Turner m_match_info.GetGroupID() != proc_info.GetGroupID())
281805e7106SZachary Turner return false;
282805e7106SZachary Turner
283805e7106SZachary Turner if (m_match_info.EffectiveUserIDIsValid() &&
284805e7106SZachary Turner m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())
285805e7106SZachary Turner return false;
286805e7106SZachary Turner
287805e7106SZachary Turner if (m_match_info.EffectiveGroupIDIsValid() &&
288805e7106SZachary Turner m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
289805e7106SZachary Turner return false;
290805e7106SZachary Turner return true;
291805e7106SZachary Turner }
Matches(const ProcessInstanceInfo & proc_info) const292a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::Matches(
293a8b18baaSPavel Labath const ProcessInstanceInfo &proc_info) const {
294a8b18baaSPavel Labath return ArchitectureMatches(proc_info.GetArchitecture()) &&
295a8b18baaSPavel Labath ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&
296a8b18baaSPavel Labath NameMatches(proc_info.GetName());
297a8b18baaSPavel Labath }
298805e7106SZachary Turner
MatchAllProcesses() const299805e7106SZachary Turner bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
300805e7106SZachary Turner if (m_name_match_type != NameMatch::Ignore)
301805e7106SZachary Turner return false;
302805e7106SZachary Turner
303805e7106SZachary Turner if (m_match_info.ProcessIDIsValid())
304805e7106SZachary Turner return false;
305805e7106SZachary Turner
306805e7106SZachary Turner if (m_match_info.ParentProcessIDIsValid())
307805e7106SZachary Turner return false;
308805e7106SZachary Turner
309805e7106SZachary Turner if (m_match_info.UserIDIsValid())
310805e7106SZachary Turner return false;
311805e7106SZachary Turner
312805e7106SZachary Turner if (m_match_info.GroupIDIsValid())
313805e7106SZachary Turner return false;
314805e7106SZachary Turner
315805e7106SZachary Turner if (m_match_info.EffectiveUserIDIsValid())
316805e7106SZachary Turner return false;
317805e7106SZachary Turner
318805e7106SZachary Turner if (m_match_info.EffectiveGroupIDIsValid())
319805e7106SZachary Turner return false;
320805e7106SZachary Turner
321805e7106SZachary Turner if (m_match_info.GetArchitecture().IsValid())
322805e7106SZachary Turner return false;
323805e7106SZachary Turner
324805e7106SZachary Turner if (m_match_all_users)
325805e7106SZachary Turner return false;
326805e7106SZachary Turner
327805e7106SZachary Turner return true;
328805e7106SZachary Turner }
329805e7106SZachary Turner
Clear()330805e7106SZachary Turner void ProcessInstanceInfoMatch::Clear() {
331805e7106SZachary Turner m_match_info.Clear();
332805e7106SZachary Turner m_name_match_type = NameMatch::Ignore;
333805e7106SZachary Turner m_match_all_users = false;
334805e7106SZachary Turner }
3350ce3b710SJonas Devlieghere
mapping(IO & io,ProcessInstanceInfo & Info)3360ce3b710SJonas Devlieghere void llvm::yaml::MappingTraits<ProcessInstanceInfo>::mapping(
3370ce3b710SJonas Devlieghere IO &io, ProcessInstanceInfo &Info) {
3380ce3b710SJonas Devlieghere io.mapRequired("executable", Info.m_executable);
3390ce3b710SJonas Devlieghere io.mapRequired("arg0", Info.m_arg0);
340bad61548SJonas Devlieghere io.mapRequired("args", Info.m_arguments);
3410ce3b710SJonas Devlieghere io.mapRequired("arch", Info.m_arch);
3420ce3b710SJonas Devlieghere io.mapRequired("uid", Info.m_uid);
3430ce3b710SJonas Devlieghere io.mapRequired("gid", Info.m_gid);
3440ce3b710SJonas Devlieghere io.mapRequired("pid", Info.m_pid);
3450ce3b710SJonas Devlieghere io.mapRequired("effective-uid", Info.m_euid);
3460ce3b710SJonas Devlieghere io.mapRequired("effective-gid", Info.m_egid);
3470ce3b710SJonas Devlieghere io.mapRequired("parent-pid", Info.m_parent_pid);
3480ce3b710SJonas Devlieghere }
3492451cbf0SJonas Devlieghere
3502451cbf0SJonas Devlieghere
3512451cbf0SJonas Devlieghere llvm::Optional<ProcessInstanceInfoList>
GetReplayProcessInstanceInfoList()3522451cbf0SJonas Devlieghere repro::GetReplayProcessInstanceInfoList() {
3532451cbf0SJonas Devlieghere static std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>>
3542451cbf0SJonas Devlieghere loader = repro::MultiLoader<repro::ProcessInfoProvider>::Create(
3552451cbf0SJonas Devlieghere repro::Reproducer::Instance().GetLoader());
3562451cbf0SJonas Devlieghere
3572451cbf0SJonas Devlieghere if (!loader)
3582451cbf0SJonas Devlieghere return {};
3592451cbf0SJonas Devlieghere
3602451cbf0SJonas Devlieghere llvm::Optional<std::string> nextfile = loader->GetNextFile();
3612451cbf0SJonas Devlieghere if (!nextfile)
3622451cbf0SJonas Devlieghere return {};
3632451cbf0SJonas Devlieghere
3642451cbf0SJonas Devlieghere auto error_or_file = llvm::MemoryBuffer::getFile(*nextfile);
3652451cbf0SJonas Devlieghere if (std::error_code err = error_or_file.getError())
3662451cbf0SJonas Devlieghere return {};
3672451cbf0SJonas Devlieghere
3682451cbf0SJonas Devlieghere ProcessInstanceInfoList infos;
3692451cbf0SJonas Devlieghere llvm::yaml::Input yin((*error_or_file)->getBuffer());
3702451cbf0SJonas Devlieghere yin >> infos;
3712451cbf0SJonas Devlieghere
3722451cbf0SJonas Devlieghere if (auto err = yin.error())
3732451cbf0SJonas Devlieghere return {};
3742451cbf0SJonas Devlieghere
3752451cbf0SJonas Devlieghere return infos;
3762451cbf0SJonas Devlieghere }
377