xref: /llvm-project/lldb/source/Host/common/MonitoringProcessLauncher.cpp (revision cba08bd9b2f66868d27387c4f7ea06b8150d75f7)
1 //===-- ProcessLauncherWindows.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/Core/Error.h"
11 #include "lldb/Core/Log.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Host/HostProcess.h"
14 #include "lldb/Host/MonitoringProcessLauncher.h"
15 #include "lldb/Target/Platform.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/ProcessLaunchInfo.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 MonitoringProcessLauncher::MonitoringProcessLauncher(std::unique_ptr<ProcessLauncher> delegate_launcher)
23     : m_delegate_launcher(std::move(delegate_launcher))
24 {
25 }
26 
27 HostProcess
28 MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
29 {
30     ProcessLaunchInfo resolved_info(launch_info);
31 
32     error.Clear();
33     char exe_path[PATH_MAX];
34 
35     PlatformSP host_platform_sp(Platform::GetHostPlatform());
36 
37     const ArchSpec &arch_spec = resolved_info.GetArchitecture();
38 
39     FileSpec exe_spec(resolved_info.GetExecutableFile());
40 
41     FileSpec::FileType file_type = exe_spec.GetFileType();
42     if (file_type != FileSpec::eFileTypeRegular)
43     {
44         lldb::ModuleSP exe_module_sp;
45         error = host_platform_sp->ResolveExecutable(exe_spec, arch_spec, exe_module_sp, NULL);
46 
47         if (error.Fail())
48             return HostProcess();
49 
50         if (exe_module_sp)
51             exe_spec = exe_module_sp->GetFileSpec();
52     }
53 
54     if (exe_spec.Exists())
55     {
56         exe_spec.GetPath(exe_path, sizeof(exe_path));
57     }
58     else
59     {
60         resolved_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
61         error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
62         return HostProcess();
63     }
64 
65     resolved_info.SetExecutableFile(exe_spec, false);
66     assert(!resolved_info.GetFlags().Test(eLaunchFlagLaunchInTTY));
67 
68     HostProcess process = m_delegate_launcher->LaunchProcess(resolved_info, error);
69 
70     if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID)
71     {
72         Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
73 
74         Host::MonitorChildProcessCallback callback = launch_info.GetMonitorProcessCallback();
75 
76         void *baton = nullptr;
77         bool monitor_signals = false;
78         if (callback)
79         {
80             // If the ProcessLaunchInfo specified a callback, use that.
81             baton = launch_info.GetMonitorProcessBaton();
82             monitor_signals = launch_info.GetMonitorSignals();
83         }
84         else
85         {
86             callback = Process::SetProcessExitStatus;
87         }
88 
89         process.StartMonitoring(callback, baton, monitor_signals);
90         if (log)
91             log->PutCString("started monitoring child process.");
92     }
93     else
94     {
95         // Invalid process ID, something didn't go well
96         if (error.Success())
97             error.SetErrorString("process launch failed for unknown reasons");
98     }
99     return process;
100 }
101