Hi clayborg, jingham, rnk, majnemer, scottmg,
Note: All of this is Windows specific, and I'm kind of the only person working
on this. So I'm not really sure who should review this. I'm adding Jim and
Greg, but feel free to ignore if you don't care about this. Also adding a few
Windows people from here, although if ultimately nobody cares enough to review
this, since it is entirely Windows specific, I will just go in with it.
This implements ProcessWindows::DoLaunch() in such a way that a connection is
created between LLDB and the Windows kernel that allows us to obtain
notifications of interesting things that happen in an inferior process on
Windows.
Put another way, this implements the "ptrace" part of debugging for Windows
processes.
This is complicated by some technical restrictions surrounding how processes
are monitored for debug events on Windows. Specifically:
1) LLDB's generic process launching code expects that launching a process and
monitoring a process can be treated as two distinct operations. It is possible
to split this into two separate operations on Windows, but the code would be
very cumbersome, and it is much simpler to allow the monitoring and launching
to occur as one high level operation. This is largely because:
2) In Windows, the core debug loop (i.e. the ptrace equivalent) must happen on
the same thread that spawns the process, and this is a loop that ultimately
blocks until the process dies. Therefore, we cannot spawn the inferior process
on LLDB's main thread, which presents a complication for the design that LLDB
currently uses which expects launching a process to be a synchronous operation,
after which monitoring can begin.
The solution to these problems implemented here is for ProcessWindows to
completely circumvent Host::LaunchProcess. When ProcessWindows is initialized
at program startup, we create a single background thread. This background
thread does two things:
a) Pump an application-specific message queue and wait for messages from the
main thread that tell it to do things (e.g. launching processes, attaching to
processes etc).
b) When we are actively debugging processes (as a result of messages received
by step a described above), also pump Windows' message queue for events related
to processes we're debugging.
http://reviews.llvm.org/D6037
Files:
include/lldb/Host/Predicate.h
source/Plugins/Process/Windows/CMakeLists.txt
source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp
source/Plugins/Process/Windows/DebugMonitorMessageResults.h
source/Plugins/Process/Windows/DebugMonitorMessages.cpp
source/Plugins/Process/Windows/DebugMonitorMessages.h
source/Plugins/Process/Windows/DebugProcessLauncher.cpp
source/Plugins/Process/Windows/DebugProcessLauncher.h
source/Plugins/Process/Windows/DebugStatusMonitorThread.cpp
source/Plugins/Process/Windows/DebugStatusMonitorThread.h
source/Plugins/Process/Windows/ProcessWindows.cpp
source/Plugins/Process/Windows/ProcessWindows.h
Index: include/lldb/Host/Predicate.h
===================================================================
--- include/lldb/Host/Predicate.h
+++ include/lldb/Host/Predicate.h
@@ -11,6 +11,7 @@
#define liblldb_Predicate_h_
#if defined(__cplusplus)
+#include "lldb/lldb-defines.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Host/Condition.h"
#include <stdint.h>
Index: source/Plugins/Process/Windows/CMakeLists.txt
===================================================================
--- source/Plugins/Process/Windows/CMakeLists.txt
+++ source/Plugins/Process/Windows/CMakeLists.txt
@@ -4,6 +4,10 @@
include_directories(../Utility)
add_lldb_library(lldbPluginProcessWindows
+ DebugMonitorMessages.cpp
+ DebugMonitorMessageResults.cpp
+ DebugProcessLauncher.cpp
+ DebugStatusMonitorThread.cpp
ProcessWindows.cpp
)
Index: source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp
@@ -0,0 +1,55 @@
+//===-- DebugMonitorMessageResults.cpp --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugMonitorMessageResults.h"
+#include "DebugMonitorMessages.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DebugMonitorMessageResult::DebugMonitorMessageResult(const DebugMonitorMessage *message)
+ : m_message(message)
+{
+ Retain();
+ if (m_message)
+ m_message->Retain();
+}
+
+DebugMonitorMessageResult::~DebugMonitorMessageResult()
+{
+ if (m_message)
+ m_message->Release();
+}
+
+void
+DebugMonitorMessageResult::SetError(const Error &error)
+{
+ m_error = error;
+}
+
+LaunchProcessMessageResult::LaunchProcessMessageResult(const LaunchProcessMessage *message)
+ : DebugMonitorMessageResult(message)
+{
+}
+
+LaunchProcessMessageResult *
+LaunchProcessMessageResult::Create(const LaunchProcessMessage *message)
+{
+ return new LaunchProcessMessageResult(message);
+}
+
+void
+LaunchProcessMessageResult::SetProcess(const HostProcess &process)
+{
+ m_process = process;
+}
Index: source/Plugins/Process/Windows/DebugMonitorMessageResults.h
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugMonitorMessageResults.h
@@ -0,0 +1,70 @@
+//===-- DebugMonitorMessages.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_DebugMonitorMessageResults_H_
+#define liblldb_Plugins_Process_Windows_DebugMonitorMessageResults_H_
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/HostProcess.h"
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+namespace lldb_private
+{
+
+class DebugMonitorMessage;
+class DebugMonitorMessageResult;
+class LaunchProcessMessage;
+
+class DebugMonitorMessageResult : public llvm::ThreadSafeRefCountedBase<DebugMonitorMessageResult>
+{
+ public:
+ virtual ~DebugMonitorMessageResult();
+
+ const Error &
+ GetError() const
+ {
+ return m_error;
+ }
+ const DebugMonitorMessage *
+ GetOriginalMessage() const
+ {
+ return m_message;
+ }
+
+ void SetError(const Error &error);
+
+ protected:
+ DebugMonitorMessageResult(const DebugMonitorMessage *message);
+
+ private:
+ Error m_error;
+ const DebugMonitorMessage *m_message;
+};
+
+class LaunchProcessMessageResult : public DebugMonitorMessageResult
+{
+ public:
+ static LaunchProcessMessageResult *Create(const LaunchProcessMessage *message);
+
+ void SetProcess(const HostProcess &process);
+ const HostProcess &
+ GetProcess() const
+ {
+ return m_process;
+ }
+
+ private:
+ LaunchProcessMessageResult(const LaunchProcessMessage *message);
+
+ HostProcess m_process;
+};
+}
+
+#endif
Index: source/Plugins/Process/Windows/DebugMonitorMessages.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugMonitorMessages.cpp
@@ -0,0 +1,61 @@
+//===-- DebugMonitorMessages.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugMonitorMessages.h"
+#include "DebugMonitorMessageResults.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DebugMonitorMessage::DebugMonitorMessage(MonitorMessageType message_type)
+ : m_message_type(message_type)
+{
+ Retain();
+ m_completion_predicate.SetValue(nullptr, eBroadcastNever);
+}
+
+DebugMonitorMessage::~DebugMonitorMessage()
+{
+ const DebugMonitorMessageResult *result = m_completion_predicate.GetValue();
+ if (result)
+ result->Release();
+ m_completion_predicate.SetValue(nullptr, eBroadcastNever);
+}
+
+const DebugMonitorMessageResult *
+DebugMonitorMessage::WaitForCompletion()
+{
+ const DebugMonitorMessageResult *result = nullptr;
+ m_completion_predicate.WaitForValueNotEqualTo(nullptr, result);
+ return result;
+}
+
+void
+DebugMonitorMessage::CompleteMessage(const DebugMonitorMessageResult *result)
+{
+ if (result)
+ result->Retain();
+ m_completion_predicate.SetValue(result, eBroadcastAlways);
+}
+
+LaunchProcessMessage::LaunchProcessMessage(const ProcessLaunchInfo &launch_info)
+ : DebugMonitorMessage(MonitorMessageType::eLaunchProcess)
+ , m_launch_info(launch_info)
+{
+}
+
+LaunchProcessMessage *
+LaunchProcessMessage::Create(const ProcessLaunchInfo &launch_info)
+{
+ return new LaunchProcessMessage(launch_info);
+}
Index: source/Plugins/Process/Windows/DebugMonitorMessages.h
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugMonitorMessages.h
@@ -0,0 +1,80 @@
+//===-- DebugMonitorMessages.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_DebugMonitorMessages_H_
+#define liblldb_Plugins_Process_Windows_DebugMonitorMessages_H_
+
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ProcessStatusMonitor.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+
+#include <map>
+#include <memory>
+
+class ProcessWindows;
+
+namespace lldb_private
+{
+class DebugMonitorMessage;
+class DebugMonitorMessageResult;
+class ProcessLaunchInfo;
+
+enum class MonitorMessageType
+{
+ eLaunchProcess, // Launch a process under the control of the debugger.
+ eAttachProcess, // Attach to an existing process, and give control to the debugger.
+ eDetachProcess, // Detach from a process that the debugger currently controls.
+ eSuspendProcess, // Suspend a process.
+ eResumeProcess, // Resume a suspended process.
+};
+
+class DebugMonitorMessage : public llvm::ThreadSafeRefCountedBase<DebugMonitorMessage>
+{
+ public:
+ virtual ~DebugMonitorMessage();
+
+ const DebugMonitorMessageResult *WaitForCompletion();
+ void CompleteMessage(const DebugMonitorMessageResult *result);
+
+ MonitorMessageType
+ GetMessageType() const
+ {
+ return m_message_type;
+ }
+
+ protected:
+ DebugMonitorMessage(MonitorMessageType message_type);
+
+ private:
+ Predicate<const DebugMonitorMessageResult *> m_completion_predicate;
+ MonitorMessageType m_message_type;
+};
+
+class LaunchProcessMessage : public DebugMonitorMessage
+{
+ public:
+ static LaunchProcessMessage *Create(const ProcessLaunchInfo &launch_info);
+ const ProcessLaunchInfo &
+ GetLaunchInfo() const
+ {
+ return m_launch_info;
+ }
+
+ private:
+ LaunchProcessMessage(const ProcessLaunchInfo &launch_info);
+
+ const ProcessLaunchInfo &m_launch_info;
+};
+}
+
+#endif
Index: source/Plugins/Process/Windows/DebugProcessLauncher.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugProcessLauncher.cpp
@@ -0,0 +1,38 @@
+//===-- DebugProcessLauncher.cpp --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugMonitorMessages.h"
+#include "DebugMonitorMessageResults.h"
+#include "DebugProcessLauncher.h"
+#include "DebugStatusMonitorThread.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DebugProcessLauncher::DebugProcessLauncher(lldb::ProcessSP process)
+ : m_process(process)
+{
+}
+
+HostProcess
+DebugProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
+{
+ LaunchProcessMessage *message = LaunchProcessMessage::Create(launch_info);
+ DebugStatusMonitorThread::GetInstance().PostDebugMessage(message);
+ const LaunchProcessMessageResult *result = static_cast<const LaunchProcessMessageResult *>(message->WaitForCompletion());
+ error = result->GetError();
+ HostProcess process = result->GetProcess();
+
+ message->Release();
+ return process;
+}
Index: source/Plugins/Process/Windows/DebugProcessLauncher.h
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugProcessLauncher.h
@@ -0,0 +1,40 @@
+//===-- DebugProcessLauncher.h ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_DebugProcessLauncher_H_
+#define liblldb_Plugins_Process_Windows_DebugProcessLauncher_H_
+
+#include "lldb/Host/ProcessLauncher.h"
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+// DebugProcessLauncher
+//
+// DebugProcessLauncher launches a process for debugging on Windows. On
+// Windows, the debug loop that detects events and status changes in a debugged
+// process must run on the same thread that calls CreateProcess. So
+// DebugProcessLauncher is built with this in mind. It queues a request to the
+// DebugStatusMonitorThread to launch a new process, then waits for a
+// notification from that thread that the launch is complete.
+//----------------------------------------------------------------------
+class DebugProcessLauncher : public ProcessLauncher
+{
+ public:
+ DebugProcessLauncher(lldb::ProcessSP process);
+ virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error);
+
+ private:
+ lldb::ProcessSP m_process;
+};
+}
+
+#endif
Index: source/Plugins/Process/Windows/DebugStatusMonitorThread.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugStatusMonitorThread.cpp
@@ -0,0 +1,185 @@
+//===-- DebugStatusMonitorThread.cpp ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugMonitorMessages.h"
+#include "DebugMonitorMessageResults.h"
+#include "DebugStatusMonitorThread.h"
+
+#include "lldb/Host/windows/ProcessLauncherWindows.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Target/Process.h"
+
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+DebugStatusMonitorThread *DebugStatusMonitorThread::m_instance = NULL;
+
+DebugStatusMonitorThread::DebugStatusMonitorThread()
+{
+ m_monitor_thread = ThreadLauncher::LaunchThread("lldb.plugin.process-windows.monitor-thread", MonitorThread, this, nullptr);
+ m_shutdown_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_monitor_event = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+ ::CreatePipe(&m_monitor_pipe_read, &m_monitor_pipe_write, NULL, 1024);
+}
+
+void
+DebugStatusMonitorThread::Initialize()
+{
+ m_instance = new DebugStatusMonitorThread();
+}
+
+void
+DebugStatusMonitorThread::Teardown()
+{
+ delete m_instance;
+ m_instance = nullptr;
+}
+
+DebugStatusMonitorThread &
+DebugStatusMonitorThread::GetInstance()
+{
+ return *m_instance;
+}
+
+void
+DebugStatusMonitorThread::PostDebugMessage(const DebugMonitorMessage *message)
+{
+ message->Retain();
+ if (!::WriteFile(m_monitor_pipe_write, &message, sizeof(message), NULL, NULL))
+ {
+ message->Release();
+ return;
+ }
+
+ ::SetEvent(m_monitor_event);
+}
+
+const DebugMonitorMessageResult *
+DebugStatusMonitorThread::HandleMonitorMessage(const DebugMonitorMessage *message)
+{
+ switch (message->GetMessageType())
+ {
+ case MonitorMessageType::eLaunchProcess:
+ {
+ const auto *launch_message = static_cast<const LaunchProcessMessage *>(message);
+ return HandleMonitorMessage(launch_message);
+ }
+ default:
+ return nullptr;
+ }
+}
+
+const LaunchProcessMessageResult *
+DebugStatusMonitorThread::HandleMonitorMessage(const LaunchProcessMessage *launch_message)
+{
+ Error error;
+ ProcessLauncherWindows launcher;
+ HostProcess process = launcher.LaunchProcess(launch_message->GetLaunchInfo(), error);
+ LaunchProcessMessageResult *result = LaunchProcessMessageResult::Create(launch_message);
+
+ if (error.Success())
+ {
+ auto iter = m_debugged_processes.find(process.GetProcessId());
+ if (iter == m_debugged_processes.end())
+ {
+ MonitorData *data = new MonitorData;
+ data->m_host_process = process;
+ // If we've never seen this pid before, make a new entry for it in the map.
+ m_debugged_processes.insert(std::make_pair(process.GetProcessId(), data));
+ result->SetProcess(process);
+ }
+ else
+ {
+ // Otherwise log an error of some kind, this shouldn't happen. Do we have a stale process
+ // entry or something?
+ }
+ }
+
+ result->SetError(error);
+ return result;
+}
+
+bool
+DebugStatusMonitorThread::ProcessMonitorMessages()
+{
+ DWORD bytes_available = 0;
+ if (!PeekNamedPipe(m_monitor_pipe_read, NULL, 0, NULL, &bytes_available, NULL))
+ {
+ // There's some kind of error with the named pipe. Fail out and stop monitoring.
+ return false;
+ }
+
+ if (bytes_available <= 0)
+ {
+ // There's no data available, but the operation succeeded.
+ return true;
+ }
+
+ int count = bytes_available / sizeof(DebugMonitorMessage *);
+ std::vector<DebugMonitorMessage *> messages(count);
+ if (!::ReadFile(m_monitor_pipe_read, &messages[0], bytes_available, NULL, NULL))
+ return false;
+
+ for (DebugMonitorMessage *message : messages)
+ {
+ const DebugMonitorMessageResult *result = HandleMonitorMessage(message);
+ message->CompleteMessage(result);
+ message->Release();
+ }
+ return true;
+}
+
+lldb::thread_result_t
+DebugStatusMonitorThread::MonitorThread(void *data)
+{
+ DebugStatusMonitorThread *monitor_thread = static_cast<DebugStatusMonitorThread *>(data);
+
+ while (true)
+ {
+ // See if any new processes are ready for debug monitoring.
+ DWORD result = WaitForSingleObject(monitor_thread->m_monitor_event, 1000);
+ if (result != WAIT_OBJECT_0 && result != WAIT_TIMEOUT)
+ {
+ // Some kind of error occurred.
+ break;
+ }
+
+ if (result != WAIT_TIMEOUT)
+ monitor_thread->ProcessMonitorMessages();
+
+ if (monitor_thread->m_debugged_processes.empty())
+ continue;
+
+ // Empty out the debug event queue before checking whether new processes are trying to be
+ // debugged. Don't spend alot of time blocking on this, because we want LLDB to be
+ // responsive to launching new processes under a debugger.
+ DEBUG_EVENT debug_event = {0};
+ while (WaitForDebugEvent(&debug_event, 500))
+ {
+ auto iter = monitor_thread->m_debugged_processes.find(debug_event.dwProcessId);
+ if (iter != monitor_thread->m_debugged_processes.end())
+ {
+ MonitorData *monitor_data = iter->second;
+ if (debug_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
+ {
+ // The process exited, remove it from the set of monitored processes.
+ Process::SetProcessExitStatus(nullptr, monitor_data->m_host_process.GetProcessId(), true, 0, 0);
+ delete monitor_data;
+ monitor_thread->m_debugged_processes.erase(iter);
+ iter = monitor_thread->m_debugged_processes.end();
+ }
+ }
+ ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_CONTINUE);
+ }
+ }
+
+ return 0;
+}
Index: source/Plugins/Process/Windows/DebugStatusMonitorThread.h
===================================================================
--- /dev/null
+++ source/Plugins/Process/Windows/DebugStatusMonitorThread.h
@@ -0,0 +1,74 @@
+//===-- DebugStatusMonitorThread.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_DebugStatusMonitorThread_H_
+#define liblldb_Plugins_Process_Windows_DebugStatusMonitorThread_H_
+
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ProcessStatusMonitor.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-types.h"
+
+#include <map>
+
+class ProcessWindows;
+
+namespace lldb_private
+{
+class DebugMonitorMessage;
+class DebugMonitorMessageResult;
+class LaunchProcessMessage;
+class LaunchProcessMessageResult;
+
+//----------------------------------------------------------------------
+// DebugStatusMonitorThread
+//
+// Runs a background thread that monitors for debug events from multiple
+// processes, and invokes callbacks as events occur for the various processes.
+//----------------------------------------------------------------------
+class DebugStatusMonitorThread
+{
+ struct MonitorData
+ {
+ HostProcess m_host_process;
+ lldb::ProcessSP m_plugin;
+ };
+
+ public:
+ virtual ~DebugStatusMonitorThread() {}
+
+ static void Initialize();
+ static void Teardown();
+ static DebugStatusMonitorThread &GetInstance();
+
+ void PostDebugMessage(const DebugMonitorMessage *message);
+ void StartMonitoring(const HostProcess &host_process, lldb::ProcessSP plugin, ProcessStatusMonitorCallbackListUP callbacks);
+
+ private:
+ DebugStatusMonitorThread();
+
+ bool ProcessMonitorMessages();
+ const DebugMonitorMessageResult *HandleMonitorMessage(const DebugMonitorMessage *message);
+ const LaunchProcessMessageResult *HandleMonitorMessage(const LaunchProcessMessage *launch_message);
+
+ static DebugStatusMonitorThread *m_instance;
+
+ std::map<lldb::pid_t, MonitorData *> m_debugged_processes;
+
+ HANDLE m_monitor_event;
+ HANDLE m_shutdown_event;
+ HANDLE m_monitor_pipe_read;
+ HANDLE m_monitor_pipe_write;
+ lldb_private::HostThread m_monitor_thread;
+
+ static lldb::thread_result_t MonitorThread(void *data);
+};
+}
+
+#endif
Index: source/Plugins/Process/Windows/ProcessWindows.cpp
===================================================================
--- source/Plugins/Process/Windows/ProcessWindows.cpp
+++ source/Plugins/Process/Windows/ProcessWindows.cpp
@@ -11,18 +11,26 @@
#include "lldb/Host/windows/windows.h"
// C++ Includes
+#include <vector>
+
// Other libraries and framework includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/MonitoringProcessLauncher.h"
+#include "lldb/Host/ProcessStatusMonitor.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/ExitStatusMonitorWindows.h"
#include "lldb/Host/windows/ProcessLauncherWindows.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Target.h"
+#include "DebugProcessLauncher.h"
+#include "DebugStatusMonitorThread.h"
#include "ProcessWindows.h"
using namespace lldb;
@@ -48,6 +56,7 @@
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
CreateInstance);
+ DebugStatusMonitorThread::Initialize();
}
}
@@ -59,9 +68,14 @@
{
}
+ProcessWindows::~ProcessWindows()
+{
+}
+
void
ProcessWindows::Terminate()
{
+ DebugStatusMonitorThread::Teardown();
}
lldb_private::ConstString
@@ -89,7 +103,36 @@
ProcessWindows::DoLaunch(Module *exe_module,
ProcessLaunchInfo &launch_info)
{
- return Host::LaunchProcess(launch_info);
+ Error result;
+ HostProcess process;
+ SetPrivateState(eStateLaunching);
+ if (launch_info.GetFlags().Test(eLaunchFlagDebug))
+ {
+ // If we're trying to debug this process, we need to use a
+ // DebugProcessLauncher so that we can enter a WaitForDebugEvent loop
+ // on the same thread that does the CreateProcess.
+ DebugProcessLauncher launcher(shared_from_this());
+ process = launcher.LaunchProcess(launch_info, result);
+ }
+ else
+ {
+ // If we're not trying to debug this process, use a standard launcher
+ // and only monitor for the process's exit, and not other types of debug
+ // events.
+ ProcessLauncherUP delegate_launcher;
+ ProcessStatusMonitorSP status_monitor;
+ delegate_launcher.reset(new ProcessLauncherWindows());
+ status_monitor.reset(new ExitStatusMonitor());
+ MonitoringProcessLauncher launcher(status_monitor, std::move(delegate_launcher));
+ process = launcher.LaunchProcess(launch_info, result);
+ }
+
+ if (!result.Success())
+ return result;
+
+ launch_info.SetProcessID(process.GetProcessId());
+ SetID(process.GetProcessId());
+ return result;
}
Error
@@ -181,4 +224,3 @@
return exe_module_sp->GetFileSpec().Exists();
return false;
}
-
Index: source/Plugins/Process/Windows/ProcessWindows.h
===================================================================
--- source/Plugins/Process/Windows/ProcessWindows.h
+++ source/Plugins/Process/Windows/ProcessWindows.h
@@ -13,13 +13,21 @@
// C Includes
// C++ Includes
+#include <map>
#include <queue>
// Other libraries and framework includes
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/ProcessStatusMonitor.h"
#include "lldb/Target/Process.h"
class ProcessMonitor;
+namespace lldb_private
+{
+class HostProcess;
+}
+
class ProcessWindows :
public lldb_private::Process
{
@@ -50,6 +58,8 @@
ProcessWindows(lldb_private::Target& target,
lldb_private::Listener &listener);
+ ~ProcessWindows();
+
virtual lldb_private::Error
DoDetach(bool keep_stopped);
@@ -99,11 +109,7 @@
virtual bool
IsAlive ();
- virtual size_t
- DoReadMemory (lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- lldb_private::Error &error);
+ virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, lldb_private::Error &error);
};
#endif // liblldb_Plugins_Process_Windows_ProcessWindows_H_
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits