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"
12*bb894b97SJonas 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 
24805e7106SZachary Turner ProcessInfo::ProcessInfo()
25805e7106SZachary Turner     : m_executable(), m_arguments(), m_environment(), m_uid(UINT32_MAX),
26805e7106SZachary Turner       m_gid(UINT32_MAX), m_arch(), m_pid(LLDB_INVALID_PROCESS_ID) {}
27805e7106SZachary Turner 
28805e7106SZachary Turner ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch,
29805e7106SZachary Turner                          lldb::pid_t pid)
30805e7106SZachary Turner     : m_executable(name), m_arguments(), m_environment(), m_uid(UINT32_MAX),
31805e7106SZachary Turner       m_gid(UINT32_MAX), m_arch(arch), m_pid(pid) {}
32805e7106SZachary Turner 
33805e7106SZachary Turner void ProcessInfo::Clear() {
34805e7106SZachary Turner   m_executable.Clear();
35805e7106SZachary Turner   m_arguments.Clear();
36805e7106SZachary Turner   m_environment.clear();
37805e7106SZachary Turner   m_uid = UINT32_MAX;
38805e7106SZachary Turner   m_gid = UINT32_MAX;
39805e7106SZachary Turner   m_arch.Clear();
40805e7106SZachary Turner   m_pid = LLDB_INVALID_PROCESS_ID;
41805e7106SZachary Turner }
42805e7106SZachary Turner 
43805e7106SZachary Turner const char *ProcessInfo::GetName() const {
44805e7106SZachary Turner   return m_executable.GetFilename().GetCString();
45805e7106SZachary Turner }
46805e7106SZachary Turner 
4772ca5f36SRaphael Isemann llvm::StringRef ProcessInfo::GetNameAsStringRef() const {
4872ca5f36SRaphael Isemann   return m_executable.GetFilename().GetStringRef();
49805e7106SZachary Turner }
50805e7106SZachary Turner 
51805e7106SZachary Turner void ProcessInfo::Dump(Stream &s, Platform *platform) const {
52805e7106SZachary Turner   s << "Executable: " << GetName() << "\n";
53805e7106SZachary Turner   s << "Triple: ";
542f1e7b3dSRaphael Isemann   m_arch.DumpTriple(s.AsRawOstream());
55805e7106SZachary Turner   s << "\n";
56805e7106SZachary Turner 
57805e7106SZachary Turner   s << "Arguments:\n";
58805e7106SZachary Turner   m_arguments.Dump(s);
59805e7106SZachary Turner 
60805e7106SZachary Turner   s.Format("Environment:\n{0}", m_environment);
61805e7106SZachary Turner }
62805e7106SZachary Turner 
63805e7106SZachary Turner void ProcessInfo::SetExecutableFile(const FileSpec &exe_file,
64805e7106SZachary Turner                                     bool add_exe_file_as_first_arg) {
65805e7106SZachary Turner   if (exe_file) {
66805e7106SZachary Turner     m_executable = exe_file;
67805e7106SZachary Turner     if (add_exe_file_as_first_arg) {
68805e7106SZachary Turner       llvm::SmallString<128> filename;
69805e7106SZachary Turner       exe_file.GetPath(filename);
70805e7106SZachary Turner       if (!filename.empty())
71805e7106SZachary Turner         m_arguments.InsertArgumentAtIndex(0, filename);
72805e7106SZachary Turner     }
73805e7106SZachary Turner   } else {
74805e7106SZachary Turner     m_executable.Clear();
75805e7106SZachary Turner   }
76805e7106SZachary Turner }
77805e7106SZachary Turner 
78805e7106SZachary Turner llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; }
79805e7106SZachary Turner 
80adcd0268SBenjamin Kramer void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); }
81805e7106SZachary Turner 
82805e7106SZachary Turner void ProcessInfo::SetArguments(char const **argv,
83805e7106SZachary Turner                                bool first_arg_is_executable) {
84805e7106SZachary Turner   m_arguments.SetArguments(argv);
85805e7106SZachary Turner 
86805e7106SZachary Turner   // Is the first argument the executable?
87805e7106SZachary Turner   if (first_arg_is_executable) {
88805e7106SZachary Turner     const char *first_arg = m_arguments.GetArgumentAtIndex(0);
89805e7106SZachary Turner     if (first_arg) {
90805e7106SZachary Turner       // Yes the first argument is an executable, set it as the executable in
91805e7106SZachary Turner       // the launch options. Don't resolve the file path as the path could be a
92805e7106SZachary Turner       // remote platform path
93805e7106SZachary Turner       m_executable.SetFile(first_arg, FileSpec::Style::native);
94805e7106SZachary Turner     }
95805e7106SZachary Turner   }
96805e7106SZachary Turner }
97805e7106SZachary Turner 
98805e7106SZachary Turner void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) {
99805e7106SZachary Turner   // Copy all arguments
100805e7106SZachary Turner   m_arguments = args;
101805e7106SZachary Turner 
102805e7106SZachary Turner   // Is the first argument the executable?
103805e7106SZachary Turner   if (first_arg_is_executable) {
104805e7106SZachary Turner     const char *first_arg = m_arguments.GetArgumentAtIndex(0);
105805e7106SZachary Turner     if (first_arg) {
106805e7106SZachary Turner       // Yes the first argument is an executable, set it as the executable in
107805e7106SZachary Turner       // the launch options. Don't resolve the file path as the path could be a
108805e7106SZachary Turner       // remote platform path
109805e7106SZachary Turner       m_executable.SetFile(first_arg, FileSpec::Style::native);
110805e7106SZachary Turner     }
111805e7106SZachary Turner   }
112805e7106SZachary Turner }
113805e7106SZachary Turner 
114805e7106SZachary Turner void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const {
115805e7106SZachary Turner   if (m_pid != LLDB_INVALID_PROCESS_ID)
116805e7106SZachary Turner     s.Printf("    pid = %" PRIu64 "\n", m_pid);
117805e7106SZachary Turner 
118805e7106SZachary Turner   if (m_parent_pid != LLDB_INVALID_PROCESS_ID)
119805e7106SZachary Turner     s.Printf(" parent = %" PRIu64 "\n", m_parent_pid);
120805e7106SZachary Turner 
121805e7106SZachary Turner   if (m_executable) {
122805e7106SZachary Turner     s.Printf("   name = %s\n", m_executable.GetFilename().GetCString());
123805e7106SZachary Turner     s.PutCString("   file = ");
1244dac97ebSRaphael Isemann     m_executable.Dump(s.AsRawOstream());
125805e7106SZachary Turner     s.EOL();
126805e7106SZachary Turner   }
127805e7106SZachary Turner   const uint32_t argc = m_arguments.GetArgumentCount();
128805e7106SZachary Turner   if (argc > 0) {
129805e7106SZachary Turner     for (uint32_t i = 0; i < argc; i++) {
130805e7106SZachary Turner       const char *arg = m_arguments.GetArgumentAtIndex(i);
131805e7106SZachary Turner       if (i < 10)
132805e7106SZachary Turner         s.Printf(" arg[%u] = %s\n", i, arg);
133805e7106SZachary Turner       else
134805e7106SZachary Turner         s.Printf("arg[%u] = %s\n", i, arg);
135805e7106SZachary Turner     }
136805e7106SZachary Turner   }
137805e7106SZachary Turner 
138805e7106SZachary Turner   s.Format("{0}", m_environment);
139805e7106SZachary Turner 
140805e7106SZachary Turner   if (m_arch.IsValid()) {
141805e7106SZachary Turner     s.Printf("   arch = ");
1422f1e7b3dSRaphael Isemann     m_arch.DumpTriple(s.AsRawOstream());
143805e7106SZachary Turner     s.EOL();
144805e7106SZachary Turner   }
145805e7106SZachary Turner 
146805e7106SZachary Turner   if (UserIDIsValid()) {
147805e7106SZachary Turner     s.Format("    uid = {0,-5} ({1})\n", GetUserID(),
148805e7106SZachary Turner              resolver.GetUserName(GetUserID()).getValueOr(""));
149805e7106SZachary Turner   }
150805e7106SZachary Turner   if (GroupIDIsValid()) {
151805e7106SZachary Turner     s.Format("    gid = {0,-5} ({1})\n", GetGroupID(),
152805e7106SZachary Turner              resolver.GetGroupName(GetGroupID()).getValueOr(""));
153805e7106SZachary Turner   }
154805e7106SZachary Turner   if (EffectiveUserIDIsValid()) {
155805e7106SZachary Turner     s.Format("   euid = {0,-5} ({1})\n", GetEffectiveUserID(),
156805e7106SZachary Turner              resolver.GetUserName(GetEffectiveUserID()).getValueOr(""));
157805e7106SZachary Turner   }
158805e7106SZachary Turner   if (EffectiveGroupIDIsValid()) {
159805e7106SZachary Turner     s.Format("   egid = {0,-5} ({1})\n", GetEffectiveGroupID(),
160805e7106SZachary Turner              resolver.GetGroupName(GetEffectiveGroupID()).getValueOr(""));
161805e7106SZachary Turner   }
162805e7106SZachary Turner }
163805e7106SZachary Turner 
164805e7106SZachary Turner void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,
165805e7106SZachary Turner                                           bool verbose) {
166805e7106SZachary Turner   const char *label;
167805e7106SZachary Turner   if (show_args || verbose)
168805e7106SZachary Turner     label = "ARGUMENTS";
169805e7106SZachary Turner   else
170805e7106SZachary Turner     label = "NAME";
171805e7106SZachary Turner 
172805e7106SZachary Turner   if (verbose) {
173805e7106SZachary Turner     s.Printf("PID    PARENT USER       GROUP      EFF USER   EFF GROUP  TRIPLE "
174805e7106SZachary Turner              "                        %s\n",
175805e7106SZachary Turner              label);
176e0a398bfSWalter Erquinigo     s.PutCString(
177e0a398bfSWalter Erquinigo         "====== ====== ========== ========== ========== ========== "
178e0a398bfSWalter Erquinigo         "============================== ============================\n");
179805e7106SZachary Turner   } else {
180e0a398bfSWalter Erquinigo     s.Printf("PID    PARENT USER       TRIPLE                         %s\n",
181e0a398bfSWalter Erquinigo              label);
182e0a398bfSWalter Erquinigo     s.PutCString("====== ====== ========== ============================== "
183805e7106SZachary Turner                  "============================\n");
184805e7106SZachary Turner   }
185805e7106SZachary Turner }
186805e7106SZachary Turner 
187805e7106SZachary Turner void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
188805e7106SZachary Turner                                          bool show_args, bool verbose) const {
189805e7106SZachary Turner   if (m_pid != LLDB_INVALID_PROCESS_ID) {
190805e7106SZachary Turner     s.Printf("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
191805e7106SZachary Turner 
192805e7106SZachary Turner     StreamString arch_strm;
193805e7106SZachary Turner     if (m_arch.IsValid())
1942f1e7b3dSRaphael Isemann       m_arch.DumpTriple(arch_strm.AsRawOstream());
195805e7106SZachary Turner 
196602f29fdSPavel Labath     auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,
197602f29fdSPavel Labath                      uint32_t (ProcessInstanceInfo::*getID)() const,
198602f29fdSPavel Labath                      llvm::Optional<llvm::StringRef> (UserIDResolver::*getName)(
199805e7106SZachary Turner                          UserIDResolver::id_t id)) {
200602f29fdSPavel Labath       const char *format = "{0,-10} ";
201602f29fdSPavel Labath       if (!(this->*isValid)()) {
202602f29fdSPavel Labath         s.Format(format, "");
203602f29fdSPavel Labath         return;
204602f29fdSPavel Labath       }
205602f29fdSPavel Labath       uint32_t id = (this->*getID)();
206602f29fdSPavel Labath       if (auto name = (resolver.*getName)(id))
207602f29fdSPavel Labath         s.Format(format, *name);
208805e7106SZachary Turner       else
209602f29fdSPavel Labath         s.Format(format, id);
210805e7106SZachary Turner     };
211805e7106SZachary Turner     if (verbose) {
212602f29fdSPavel Labath       print(&ProcessInstanceInfo::UserIDIsValid,
213602f29fdSPavel Labath             &ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);
214602f29fdSPavel Labath       print(&ProcessInstanceInfo::GroupIDIsValid,
215602f29fdSPavel Labath             &ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);
216602f29fdSPavel Labath       print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
217602f29fdSPavel Labath             &ProcessInstanceInfo::GetEffectiveUserID,
218602f29fdSPavel Labath             &UserIDResolver::GetUserName);
219602f29fdSPavel Labath       print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,
220602f29fdSPavel Labath             &ProcessInstanceInfo::GetEffectiveGroupID,
221602f29fdSPavel Labath             &UserIDResolver::GetGroupName);
222805e7106SZachary Turner 
223e0a398bfSWalter Erquinigo       s.Printf("%-30s ", arch_strm.GetData());
224805e7106SZachary Turner     } else {
225602f29fdSPavel Labath       print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
226602f29fdSPavel Labath             &ProcessInstanceInfo::GetEffectiveUserID,
227602f29fdSPavel Labath             &UserIDResolver::GetUserName);
228e0a398bfSWalter Erquinigo       s.Printf("%-30s ", arch_strm.GetData());
229805e7106SZachary Turner     }
230805e7106SZachary Turner 
231805e7106SZachary Turner     if (verbose || show_args) {
23248a50ee0SWalter Erquinigo       s.PutCString(m_arg0);
233805e7106SZachary Turner       const uint32_t argc = m_arguments.GetArgumentCount();
234805e7106SZachary Turner       for (uint32_t i = 0; i < argc; i++) {
235805e7106SZachary Turner         s.PutChar(' ');
236805e7106SZachary Turner         s.PutCString(m_arguments.GetArgumentAtIndex(i));
237805e7106SZachary Turner       }
238805e7106SZachary Turner     } else {
239805e7106SZachary Turner       s.PutCString(GetName());
240805e7106SZachary Turner     }
241805e7106SZachary Turner 
242805e7106SZachary Turner     s.EOL();
243805e7106SZachary Turner   }
244805e7106SZachary Turner }
245805e7106SZachary Turner 
246a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::ArchitectureMatches(
247a8b18baaSPavel Labath     const ArchSpec &arch_spec) const {
248a8b18baaSPavel Labath   return !m_match_info.GetArchitecture().IsValid() ||
249a8b18baaSPavel Labath          m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);
250a8b18baaSPavel Labath }
251a8b18baaSPavel Labath 
252805e7106SZachary Turner bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
253a8b18baaSPavel Labath   if (m_name_match_type == NameMatch::Ignore)
254805e7106SZachary Turner     return true;
255805e7106SZachary Turner   const char *match_name = m_match_info.GetName();
256805e7106SZachary Turner   if (!match_name)
257805e7106SZachary Turner     return true;
258805e7106SZachary Turner 
259805e7106SZachary Turner   return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
260805e7106SZachary Turner }
261805e7106SZachary Turner 
262a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::ProcessIDsMatch(
263805e7106SZachary Turner     const ProcessInstanceInfo &proc_info) const {
264805e7106SZachary Turner   if (m_match_info.ProcessIDIsValid() &&
265805e7106SZachary Turner       m_match_info.GetProcessID() != proc_info.GetProcessID())
266805e7106SZachary Turner     return false;
267805e7106SZachary Turner 
268805e7106SZachary Turner   if (m_match_info.ParentProcessIDIsValid() &&
269805e7106SZachary Turner       m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
270805e7106SZachary Turner     return false;
271a8b18baaSPavel Labath   return true;
272a8b18baaSPavel Labath }
273805e7106SZachary Turner 
274a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::UserIDsMatch(
275a8b18baaSPavel Labath     const ProcessInstanceInfo &proc_info) const {
276805e7106SZachary Turner   if (m_match_info.UserIDIsValid() &&
277805e7106SZachary Turner       m_match_info.GetUserID() != proc_info.GetUserID())
278805e7106SZachary Turner     return false;
279805e7106SZachary Turner 
280805e7106SZachary Turner   if (m_match_info.GroupIDIsValid() &&
281805e7106SZachary Turner       m_match_info.GetGroupID() != proc_info.GetGroupID())
282805e7106SZachary Turner     return false;
283805e7106SZachary Turner 
284805e7106SZachary Turner   if (m_match_info.EffectiveUserIDIsValid() &&
285805e7106SZachary Turner       m_match_info.GetEffectiveUserID() != proc_info.GetEffectiveUserID())
286805e7106SZachary Turner     return false;
287805e7106SZachary Turner 
288805e7106SZachary Turner   if (m_match_info.EffectiveGroupIDIsValid() &&
289805e7106SZachary Turner       m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
290805e7106SZachary Turner     return false;
291805e7106SZachary Turner   return true;
292805e7106SZachary Turner }
293a8b18baaSPavel Labath bool ProcessInstanceInfoMatch::Matches(
294a8b18baaSPavel Labath     const ProcessInstanceInfo &proc_info) const {
295a8b18baaSPavel Labath   return ArchitectureMatches(proc_info.GetArchitecture()) &&
296a8b18baaSPavel Labath          ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&
297a8b18baaSPavel Labath          NameMatches(proc_info.GetName());
298a8b18baaSPavel Labath }
299805e7106SZachary Turner 
300805e7106SZachary Turner bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
301805e7106SZachary Turner   if (m_name_match_type != NameMatch::Ignore)
302805e7106SZachary Turner     return false;
303805e7106SZachary Turner 
304805e7106SZachary Turner   if (m_match_info.ProcessIDIsValid())
305805e7106SZachary Turner     return false;
306805e7106SZachary Turner 
307805e7106SZachary Turner   if (m_match_info.ParentProcessIDIsValid())
308805e7106SZachary Turner     return false;
309805e7106SZachary Turner 
310805e7106SZachary Turner   if (m_match_info.UserIDIsValid())
311805e7106SZachary Turner     return false;
312805e7106SZachary Turner 
313805e7106SZachary Turner   if (m_match_info.GroupIDIsValid())
314805e7106SZachary Turner     return false;
315805e7106SZachary Turner 
316805e7106SZachary Turner   if (m_match_info.EffectiveUserIDIsValid())
317805e7106SZachary Turner     return false;
318805e7106SZachary Turner 
319805e7106SZachary Turner   if (m_match_info.EffectiveGroupIDIsValid())
320805e7106SZachary Turner     return false;
321805e7106SZachary Turner 
322805e7106SZachary Turner   if (m_match_info.GetArchitecture().IsValid())
323805e7106SZachary Turner     return false;
324805e7106SZachary Turner 
325805e7106SZachary Turner   if (m_match_all_users)
326805e7106SZachary Turner     return false;
327805e7106SZachary Turner 
328805e7106SZachary Turner   return true;
329805e7106SZachary Turner }
330805e7106SZachary Turner 
331805e7106SZachary Turner void ProcessInstanceInfoMatch::Clear() {
332805e7106SZachary Turner   m_match_info.Clear();
333805e7106SZachary Turner   m_name_match_type = NameMatch::Ignore;
334805e7106SZachary Turner   m_match_all_users = false;
335805e7106SZachary Turner }
3360ce3b710SJonas Devlieghere 
3370ce3b710SJonas Devlieghere void llvm::yaml::MappingTraits<ProcessInstanceInfo>::mapping(
3380ce3b710SJonas Devlieghere     IO &io, ProcessInstanceInfo &Info) {
3390ce3b710SJonas Devlieghere   io.mapRequired("executable", Info.m_executable);
3400ce3b710SJonas Devlieghere   io.mapRequired("arg0", Info.m_arg0);
341bad61548SJonas Devlieghere   io.mapRequired("args", Info.m_arguments);
3420ce3b710SJonas Devlieghere   io.mapRequired("arch", Info.m_arch);
3430ce3b710SJonas Devlieghere   io.mapRequired("uid", Info.m_uid);
3440ce3b710SJonas Devlieghere   io.mapRequired("gid", Info.m_gid);
3450ce3b710SJonas Devlieghere   io.mapRequired("pid", Info.m_pid);
3460ce3b710SJonas Devlieghere   io.mapRequired("effective-uid", Info.m_euid);
3470ce3b710SJonas Devlieghere   io.mapRequired("effective-gid", Info.m_egid);
3480ce3b710SJonas Devlieghere   io.mapRequired("parent-pid", Info.m_parent_pid);
3490ce3b710SJonas Devlieghere }
3502451cbf0SJonas Devlieghere 
3512451cbf0SJonas Devlieghere 
3522451cbf0SJonas Devlieghere llvm::Optional<ProcessInstanceInfoList>
3532451cbf0SJonas Devlieghere repro::GetReplayProcessInstanceInfoList() {
3542451cbf0SJonas Devlieghere   static std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>>
3552451cbf0SJonas Devlieghere       loader = repro::MultiLoader<repro::ProcessInfoProvider>::Create(
3562451cbf0SJonas Devlieghere           repro::Reproducer::Instance().GetLoader());
3572451cbf0SJonas Devlieghere 
3582451cbf0SJonas Devlieghere   if (!loader)
3592451cbf0SJonas Devlieghere     return {};
3602451cbf0SJonas Devlieghere 
3612451cbf0SJonas Devlieghere   llvm::Optional<std::string> nextfile = loader->GetNextFile();
3622451cbf0SJonas Devlieghere   if (!nextfile)
3632451cbf0SJonas Devlieghere     return {};
3642451cbf0SJonas Devlieghere 
3652451cbf0SJonas Devlieghere   auto error_or_file = llvm::MemoryBuffer::getFile(*nextfile);
3662451cbf0SJonas Devlieghere   if (std::error_code err = error_or_file.getError())
3672451cbf0SJonas Devlieghere     return {};
3682451cbf0SJonas Devlieghere 
3692451cbf0SJonas Devlieghere   ProcessInstanceInfoList infos;
3702451cbf0SJonas Devlieghere   llvm::yaml::Input yin((*error_or_file)->getBuffer());
3712451cbf0SJonas Devlieghere   yin >> infos;
3722451cbf0SJonas Devlieghere 
3732451cbf0SJonas Devlieghere   if (auto err = yin.error())
3742451cbf0SJonas Devlieghere     return {};
3752451cbf0SJonas Devlieghere 
3762451cbf0SJonas Devlieghere   return infos;
3772451cbf0SJonas Devlieghere }
378