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