xref: /llvm-project/lldb/source/Host/common/MonitoringProcessLauncher.cpp (revision 91f14e69b8f4d2cfa3905f6c25630935682837b3)
1 //===-- MonitoringProcessLauncher.cpp ---------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Host/MonitoringProcessLauncher.h"
11 #include "lldb/Host/HostProcess.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/ProcessLaunchInfo.h"
14 #include "lldb/Utility/Log.h"
15 #include "lldb/Utility/Status.h"
16 
17 #include "llvm/Support/FileSystem.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 MonitoringProcessLauncher::MonitoringProcessLauncher(
23     std::unique_ptr<ProcessLauncher> delegate_launcher)
24     : m_delegate_launcher(std::move(delegate_launcher)) {}
25 
26 HostProcess
27 MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
28                                          Status &error) {
29   ProcessLaunchInfo resolved_info(launch_info);
30 
31   error.Clear();
32 
33   FileSpec exe_spec(resolved_info.GetExecutableFile());
34 
35   llvm::sys::fs::file_status stats;
36   status(exe_spec.GetPath(), stats);
37   if (!exists(stats)) {
38     exe_spec.ResolvePath();
39     status(exe_spec.GetPath(), stats);
40   }
41   if (!exists(stats)) {
42     exe_spec.ResolveExecutableLocation();
43     status(exe_spec.GetPath(), stats);
44   }
45 
46   if (!exists(stats)) {
47     error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
48                                     exe_spec);
49     return HostProcess();
50   }
51 
52   resolved_info.SetExecutableFile(exe_spec, false);
53   assert(!resolved_info.GetFlags().Test(eLaunchFlagLaunchInTTY));
54 
55   HostProcess process =
56       m_delegate_launcher->LaunchProcess(resolved_info, error);
57 
58   if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) {
59     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
60 
61     Host::MonitorChildProcessCallback callback =
62         launch_info.GetMonitorProcessCallback();
63 
64     bool monitor_signals = false;
65     if (callback) {
66       // If the ProcessLaunchInfo specified a callback, use that.
67       monitor_signals = launch_info.GetMonitorSignals();
68     } else {
69       callback = Process::SetProcessExitStatus;
70     }
71 
72     process.StartMonitoring(callback, monitor_signals);
73     if (log)
74       log->PutCString("started monitoring child process.");
75   } else {
76     // Invalid process ID, something didn't go well
77     if (error.Success())
78       error.SetErrorString("process launch failed for unknown reasons");
79   }
80   return process;
81 }
82