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