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 } 98