]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Host/common/MonitoringProcessLauncher.cpp
MFV r316693:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Host / common / MonitoringProcessLauncher.cpp
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/Core/Error.h"
12 #include "lldb/Core/Log.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Host/HostProcess.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(
24     std::unique_ptr<ProcessLauncher> delegate_launcher)
25     : m_delegate_launcher(std::move(delegate_launcher)) {}
26
27 HostProcess
28 MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
29                                          Error &error) {
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     ModuleSpec module_spec(exe_spec, arch_spec);
44     lldb::ModuleSP exe_module_sp;
45     error =
46         host_platform_sp->ResolveExecutable(module_spec, exe_module_sp, NULL);
47
48     if (error.Fail())
49       return HostProcess();
50
51     if (exe_module_sp)
52       exe_spec = exe_module_sp->GetFileSpec();
53   }
54
55   if (exe_spec.Exists()) {
56     exe_spec.GetPath(exe_path, sizeof(exe_path));
57   } else {
58     resolved_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
59     error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path);
60     return HostProcess();
61   }
62
63   resolved_info.SetExecutableFile(exe_spec, false);
64   assert(!resolved_info.GetFlags().Test(eLaunchFlagLaunchInTTY));
65
66   HostProcess process =
67       m_delegate_launcher->LaunchProcess(resolved_info, error);
68
69   if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) {
70     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
71
72     Host::MonitorChildProcessCallback callback =
73         launch_info.GetMonitorProcessCallback();
74
75     bool monitor_signals = false;
76     if (callback) {
77       // If the ProcessLaunchInfo specified a callback, use that.
78       monitor_signals = launch_info.GetMonitorSignals();
79     } else {
80       callback = Process::SetProcessExitStatus;
81     }
82
83     process.StartMonitoring(callback, monitor_signals);
84     if (log)
85       log->PutCString("started monitoring child process.");
86   } else {
87     // Invalid process ID, something didn't go well
88     if (error.Success())
89       error.SetErrorString("process launch failed for unknown reasons");
90   }
91   return process;
92 }