brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · 44cb333 Raw
101 lines · cpp
1//===-- HostProcessWindows.cpp --------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Host/windows/HostProcessWindows.h"10#include "lldb/Host/HostThread.h"11#include "lldb/Host/ThreadLauncher.h"12#include "lldb/Host/windows/windows.h"13#include "lldb/Utility/FileSpec.h"14 15#include "llvm/ADT/STLExtras.h"16#include "llvm/Support/ConvertUTF.h"17#include "llvm/Support/WindowsError.h"18 19#include <psapi.h>20 21using namespace lldb_private;22 23namespace {24struct MonitorInfo {25  Host::MonitorChildProcessCallback callback;26  HANDLE process_handle;27};28}29 30HostProcessWindows::HostProcessWindows()31    : HostNativeProcessBase(), m_owns_handle(true) {}32 33HostProcessWindows::HostProcessWindows(lldb::process_t process)34    : HostNativeProcessBase(process), m_owns_handle(true) {}35 36HostProcessWindows::~HostProcessWindows() { Close(); }37 38void HostProcessWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }39 40Status HostProcessWindows::Terminate() {41  Status error;42  if (m_process == nullptr)43    error = Status(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);44 45  if (!::TerminateProcess(m_process, 0))46    error = Status(::GetLastError(), lldb::eErrorTypeWin32);47 48  return error;49}50 51lldb::pid_t HostProcessWindows::GetProcessId() const {52  return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);53}54 55bool HostProcessWindows::IsRunning() const {56  if (m_process == nullptr)57    return false;58 59  DWORD code = 0;60  if (!::GetExitCodeProcess(m_process, &code))61    return false;62 63  return (code == STILL_ACTIVE);64}65 66static lldb::thread_result_t67MonitorThread(const Host::MonitorChildProcessCallback &callback,68              HANDLE process_handle) {69  DWORD exit_code;70 71  ::WaitForSingleObject(process_handle, INFINITE);72  ::GetExitCodeProcess(process_handle, &exit_code);73  callback(::GetProcessId(process_handle), 0, exit_code);74  ::CloseHandle(process_handle);75  return {};76}77 78llvm::Expected<HostThread> HostProcessWindows::StartMonitoring(79    const Host::MonitorChildProcessCallback &callback) {80  HANDLE process_handle;81 82  // Since the life of this HostProcessWindows instance and the life of the83  // process may be different, duplicate the handle so that the monitor thread84  // can have ownership over its own copy of the handle.85  if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),86                        &process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {87    return ThreadLauncher::LaunchThread(88        "ChildProcessMonitor", [callback, process_handle] {89          return MonitorThread(callback, process_handle);90        });91  } else {92    return llvm::errorCodeToError(llvm::mapWindowsError(GetLastError()));93  }94}95 96void HostProcessWindows::Close() {97  if (m_owns_handle && m_process != LLDB_INVALID_PROCESS)98    ::CloseHandle(m_process);99  m_process = nullptr;100}101