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/Host/HostProcess.h" 12 #include "lldb/Target/Process.h" 13 #include "lldb/Target/ProcessLaunchInfo.h" 14 #include "lldb/Utility/Log.h" 15 #include "lldb/Utility/Status.h" 16 17 #include "llvm/Support/FileSystem.h" 18 19 using namespace lldb; 20 using namespace lldb_private; 21 22 MonitoringProcessLauncher::MonitoringProcessLauncher( 23 std::unique_ptr<ProcessLauncher> delegate_launcher) 24 : m_delegate_launcher(std::move(delegate_launcher)) {} 25 26 HostProcess 27 MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, 28 Status &error) { 29 ProcessLaunchInfo resolved_info(launch_info); 30 31 error.Clear(); 32 33 FileSpec exe_spec(resolved_info.GetExecutableFile()); 34 35 llvm::sys::fs::file_status stats; 36 status(exe_spec.GetPath(), stats); 37 if (!exists(stats)) { 38 exe_spec.ResolvePath(); 39 status(exe_spec.GetPath(), stats); 40 } 41 if (!exists(stats)) { 42 exe_spec.ResolveExecutableLocation(); 43 status(exe_spec.GetPath(), stats); 44 } 45 46 if (!exists(stats)) { 47 error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'", 48 exe_spec); 49 return HostProcess(); 50 } 51 52 resolved_info.SetExecutableFile(exe_spec, false); 53 assert(!resolved_info.GetFlags().Test(eLaunchFlagLaunchInTTY)); 54 55 HostProcess process = 56 m_delegate_launcher->LaunchProcess(resolved_info, error); 57 58 if (process.GetProcessId() != LLDB_INVALID_PROCESS_ID) { 59 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 60 61 Host::MonitorChildProcessCallback callback = 62 launch_info.GetMonitorProcessCallback(); 63 64 bool monitor_signals = false; 65 if (callback) { 66 // If the ProcessLaunchInfo specified a callback, use that. 67 monitor_signals = launch_info.GetMonitorSignals(); 68 } else { 69 callback = Process::SetProcessExitStatus; 70 } 71 72 process.StartMonitoring(callback, monitor_signals); 73 if (log) 74 log->PutCString("started monitoring child process."); 75 } else { 76 // Invalid process ID, something didn't go well 77 if (error.Success()) 78 error.SetErrorString("process launch failed for unknown reasons"); 79 } 80 return process; 81 } 82