1 //===-- HostProcessWindows.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Host/windows/HostProcessWindows.h"
11 #include "lldb/Host/FileSpec.h"
12 #include "lldb/Host/HostThread.h"
13 #include "lldb/Host/ThreadLauncher.h"
14 #include "lldb/Host/windows/windows.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/Support/ConvertUTF.h"
21 using namespace lldb_private;
25 Host::MonitorChildProcessCallback callback;
26 HANDLE process_handle;
30 HostProcessWindows::HostProcessWindows()
31 : HostNativeProcessBase(), m_owns_handle(true) {}
33 HostProcessWindows::HostProcessWindows(lldb::process_t process)
34 : HostNativeProcessBase(process), m_owns_handle(true) {}
36 HostProcessWindows::~HostProcessWindows() { Close(); }
38 void HostProcessWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
40 Error HostProcessWindows::Terminate() {
42 if (m_process == nullptr)
43 error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
45 if (!::TerminateProcess(m_process, 0))
46 error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
51 Error HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
53 if (m_process == nullptr)
54 error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
56 std::vector<wchar_t> wpath(PATH_MAX);
57 if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size())) {
59 if (llvm::convertWideToUTF8(wpath.data(), path))
60 file_spec.SetFile(path, false);
62 error.SetErrorString("Error converting path to UTF-8");
64 error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
69 lldb::pid_t HostProcessWindows::GetProcessId() const {
70 return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);
73 bool HostProcessWindows::IsRunning() const {
74 if (m_process == nullptr)
78 if (!::GetExitCodeProcess(m_process, &code))
81 return (code == STILL_ACTIVE);
84 HostThread HostProcessWindows::StartMonitoring(
85 const Host::MonitorChildProcessCallback &callback, bool monitor_signals) {
86 HostThread monitor_thread;
87 MonitorInfo *info = new MonitorInfo;
88 info->callback = callback;
90 // Since the life of this HostProcessWindows instance and the life of the
91 // process may be different, duplicate the handle so that
92 // the monitor thread can have ownership over its own copy of the handle.
94 if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),
95 &info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
96 result = ThreadLauncher::LaunchThread("ChildProcessMonitor",
97 HostProcessWindows::MonitorThread,
102 lldb::thread_result_t HostProcessWindows::MonitorThread(void *thread_arg) {
105 MonitorInfo *info = static_cast<MonitorInfo *>(thread_arg);
107 ::WaitForSingleObject(info->process_handle, INFINITE);
108 ::GetExitCodeProcess(info->process_handle, &exit_code);
109 info->callback(::GetProcessId(info->process_handle), true, 0, exit_code);
110 ::CloseHandle(info->process_handle);
116 void HostProcessWindows::Close() {
117 if (m_owns_handle && m_process != LLDB_INVALID_PROCESS)
118 ::CloseHandle(m_process);