summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/windows
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Host/windows')
-rw-r--r--lldb/source/Host/windows/Host.cpp8
-rw-r--r--lldb/source/Host/windows/HostProcessWindows.cpp49
-rw-r--r--lldb/source/Host/windows/ProcessLauncherWindows.cpp94
3 files changed, 141 insertions, 10 deletions
diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp
index 4542025f6ee..4f698df16eb 100644
--- a/lldb/source/Host/windows/Host.cpp
+++ b/lldb/source/Host/windows/Host.cpp
@@ -96,14 +96,6 @@ namespace
}
}
-Error
-Host::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
- Error error;
- assert(!"Not implemented yet!!!");
- return error;
-}
-
lldb::DataBufferSP
Host::GetAuxvData(lldb_private::Process *process)
{
diff --git a/lldb/source/Host/windows/HostProcessWindows.cpp b/lldb/source/Host/windows/HostProcessWindows.cpp
index 447f672ac77..8388e21b853 100644
--- a/lldb/source/Host/windows/HostProcessWindows.cpp
+++ b/lldb/source/Host/windows/HostProcessWindows.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#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"
@@ -17,6 +19,16 @@
using namespace lldb_private;
+namespace
+{
+struct MonitorInfo
+{
+ HostProcess::MonitorCallback callback;
+ void *baton;
+ HANDLE process_handle;
+};
+}
+
HostProcessWindows::HostProcessWindows()
: HostNativeProcessBase()
{
@@ -61,7 +73,7 @@ Error HostProcessWindows::GetMainModule(FileSpec &file_spec) const
lldb::pid_t HostProcessWindows::GetProcessId() const
{
- return ::GetProcessId(m_process);
+ return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);
}
bool HostProcessWindows::IsRunning() const
@@ -76,9 +88,42 @@ bool HostProcessWindows::IsRunning() const
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)
+ {
+ DWORD wait_result = ::WaitForSingleObject(info->process_handle, INFINITE);
+ ::GetExitCodeProcess(info->process_handle, &exit_code);
+ info->callback(info->baton, ::GetProcessId(info->process_handle), true, 0, exit_code);
+
+ delete (info);
+ }
+ return 0;
+}
+
void HostProcessWindows::Close()
{
- if (m_process != nullptr)
+ if (m_process != LLDB_INVALID_PROCESS)
::CloseHandle(m_process);
m_process = nullptr;
}
diff --git a/lldb/source/Host/windows/ProcessLauncherWindows.cpp b/lldb/source/Host/windows/ProcessLauncherWindows.cpp
new file mode 100644
index 00000000000..7a99e0944e5
--- /dev/null
+++ b/lldb/source/Host/windows/ProcessLauncherWindows.cpp
@@ -0,0 +1,94 @@
+//===-- ProcessLauncherWindows.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/HostProcess.h"
+#include "lldb/Host/windows/ProcessLauncherWindows.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+#include <string>
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+HostProcess
+ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
+{
+ error.Clear();
+
+ std::string executable;
+ std::string commandLine;
+ std::vector<char> environment;
+ STARTUPINFO startupinfo = {0};
+ PROCESS_INFORMATION pi = {0};
+
+ HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
+ HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
+ HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
+
+ startupinfo.cb = sizeof(startupinfo);
+ startupinfo.dwFlags |= STARTF_USESTDHANDLES;
+ startupinfo.hStdError = stderr_handle;
+ startupinfo.hStdInput = stdin_handle;
+ startupinfo.hStdOutput = stdout_handle;
+
+ executable = launch_info.GetExecutableFile().GetPath();
+ launch_info.GetArguments().GetQuotedCommandString(commandLine);
+ BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL,
+ launch_info.GetWorkingDirectory(), &startupinfo, &pi);
+ if (result)
+ {
+ // Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
+ ::CloseHandle(pi.hThread);
+ }
+
+ if (stdin_handle)
+ ::CloseHandle(stdin_handle);
+ if (stdout_handle)
+ ::CloseHandle(stdout_handle);
+ if (stderr_handle)
+ ::CloseHandle(stderr_handle);
+
+ if (!result)
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ return HostProcess(pi.hProcess);
+}
+
+HANDLE
+ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd)
+{
+ const FileAction *action = launch_info.GetFileActionForFD(fd);
+ if (action == nullptr)
+ return NULL;
+ SECURITY_ATTRIBUTES secattr = {0};
+ secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ secattr.bInheritHandle = TRUE;
+
+ const char *path = action->GetPath();
+ DWORD access = 0;
+ DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ DWORD create = 0;
+ DWORD flags = 0;
+ if (fd == STDIN_FILENO)
+ {
+ access = GENERIC_READ;
+ create = OPEN_EXISTING;
+ flags = FILE_ATTRIBUTE_READONLY;
+ }
+ if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
+ {
+ access = GENERIC_WRITE;
+ create = CREATE_ALWAYS;
+ if (fd == STDERR_FILENO)
+ flags = FILE_FLAG_WRITE_THROUGH;
+ }
+
+ HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
+ return (result == INVALID_HANDLE_VALUE) ? NULL : result;
+}
OpenPOWER on IntegriCloud