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