summaryrefslogtreecommitdiff
path: root/source/Host/windows/HostProcessWindows.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-01-06 20:12:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-01-06 20:12:03 +0000
commit9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch)
treedd2a1ddf0476664c2b823409c36cbccd52662ca7 /source/Host/windows/HostProcessWindows.cpp
parent3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff)
Notes
Diffstat (limited to 'source/Host/windows/HostProcessWindows.cpp')
-rw-r--r--source/Host/windows/HostProcessWindows.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
new file mode 100644
index 0000000000000..0f81c18d34afb
--- /dev/null
+++ b/source/Host/windows/HostProcessWindows.cpp
@@ -0,0 +1,137 @@
+//===-- HostProcessWindows.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/Host/windows/HostProcessWindows.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+#include <Psapi.h>
+
+using namespace lldb_private;
+
+namespace
+{
+struct MonitorInfo
+{
+ HostProcess::MonitorCallback callback;
+ void *baton;
+ HANDLE process_handle;
+};
+}
+
+HostProcessWindows::HostProcessWindows()
+ : HostNativeProcessBase()
+ , m_owns_handle(true)
+{
+}
+
+HostProcessWindows::HostProcessWindows(lldb::process_t process)
+ : HostNativeProcessBase(process)
+ , m_owns_handle(true)
+{
+}
+
+HostProcessWindows::~HostProcessWindows()
+{
+ Close();
+}
+
+void
+HostProcessWindows::SetOwnsHandle(bool owns)
+{
+ m_owns_handle = owns;
+}
+
+Error HostProcessWindows::Terminate()
+{
+ Error error;
+ if (m_process == nullptr)
+ error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
+
+ if (!::TerminateProcess(m_process, 0))
+ error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+
+ return error;
+}
+
+Error HostProcessWindows::GetMainModule(FileSpec &file_spec) const
+{
+ Error error;
+ if (m_process == nullptr)
+ error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
+
+ char path[MAX_PATH] = { 0 };
+ if (::GetProcessImageFileName(m_process, path, llvm::array_lengthof(path)))
+ file_spec.SetFile(path, false);
+ else
+ error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+
+ return error;
+}
+
+lldb::pid_t HostProcessWindows::GetProcessId() const
+{
+ return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);
+}
+
+bool HostProcessWindows::IsRunning() const
+{
+ if (m_process == nullptr)
+ return false;
+
+ DWORD code = 0;
+ if (!::GetExitCodeProcess(m_process, &code))
+ return false;
+
+ return (code == STILL_ACTIVE);
+}
+
+HostThread
+HostProcessWindows::StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals)
+{
+ HostThread monitor_thread;
+ MonitorInfo *info = new MonitorInfo;
+ info->callback = callback;
+ info->baton = callback_baton;
+
+ // Since the life of this HostProcessWindows instance and the life of the process may be different, duplicate the handle so that
+ // the monitor thread can have ownership over its own copy of the handle.
+ HostThread result;
+ if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(), &info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ result = ThreadLauncher::LaunchThread("ChildProcessMonitor", HostProcessWindows::MonitorThread, info, nullptr);
+ return result;
+}
+
+lldb::thread_result_t
+HostProcessWindows::MonitorThread(void *thread_arg)
+{
+ DWORD exit_code;
+
+ MonitorInfo *info = static_cast<MonitorInfo *>(thread_arg);
+ if (info)
+ {
+ ::WaitForSingleObject(info->process_handle, INFINITE);
+ ::GetExitCodeProcess(info->process_handle, &exit_code);
+ info->callback(info->baton, ::GetProcessId(info->process_handle), true, 0, exit_code);
+ ::CloseHandle(info->process_handle);
+ delete (info);
+ }
+ return 0;
+}
+
+void HostProcessWindows::Close()
+{
+ if (m_owns_handle && m_process != LLDB_INVALID_PROCESS)
+ ::CloseHandle(m_process);
+ m_process = nullptr;
+}