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