[Lldb-commits] [lldb] r221207 - Implement a framework for live debugging on Windows.

Zachary Turner zturner at google.com
Mon Nov 3 16:00:12 PST 2014


Author: zturner
Date: Mon Nov  3 18:00:12 2014
New Revision: 221207

URL: http://llvm.org/viewvc/llvm-project?rev=221207&view=rev
Log:
Implement a framework for live debugging on Windows.

When processes are launched for debugging on Windows now, LLDB
will detect changes such as DLL loads and unloads, breakpoints,
thread creation and deletion, etc.

These notifications are not yet propagated to LLDB in a way that
LLDB understands what is happening with the process.  This only
picks up the notifications from the OS in a way that they can be
sent to LLDB with subsequent patches.

Reviewed by: Scott Graham

Differential Revision: http://reviews.llvm.org/D6037

Added:
    lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.cpp
    lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.h
    lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp
    lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.h
    lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.cpp
    lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.h
    lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.cpp
    lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.h
    lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.cpp
    lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.h
    lldb/trunk/source/Plugins/Process/Windows/SlaveMessages.h
Modified:
    lldb/trunk/include/lldb/Host/Predicate.h
    lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h
    lldb/trunk/source/Plugins/Process/Windows/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
    lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h

Modified: lldb/trunk/include/lldb/Host/Predicate.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Predicate.h?rev=221207&r1=221206&r2=221207&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Predicate.h (original)
+++ lldb/trunk/include/lldb/Host/Predicate.h Mon Nov  3 18:00:12 2014
@@ -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>

Modified: lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h?rev=221207&r1=221206&r2=221207&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h (original)
+++ lldb/trunk/include/lldb/Host/windows/HostThreadWindows.h Mon Nov  3 18:00:12 2014
@@ -31,9 +31,6 @@ class HostThreadWindows : public HostNat
     virtual void Reset();
 
     lldb::tid_t GetThreadId() const;
-
-  protected:
-    llvm::SmallString<32> m_thread_name;
 };
 }
 

Modified: lldb/trunk/source/Plugins/Process/Windows/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/CMakeLists.txt?rev=221207&r1=221206&r2=221207&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/Windows/CMakeLists.txt Mon Nov  3 18:00:12 2014
@@ -4,6 +4,11 @@ include_directories(.)
 include_directories(../Utility)
 
 add_lldb_library(lldbPluginProcessWindows
+  DebugMonitorMessages.cpp
+  DebugMonitorMessageResults.cpp
+  DebugOneProcessThread.cpp
+  DebugProcessLauncher.cpp
+  DebugDriverThread.cpp
   ProcessWindows.cpp
   )
 

Added: lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.cpp?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.cpp Mon Nov  3 18:00:12 2014
@@ -0,0 +1,247 @@
+//===-- DebugDriverThread.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugDriverThread.h"
+#include "DebugMonitorMessages.h"
+#include "DebugMonitorMessageResults.h"
+#include "DebugOneProcessThread.h"
+#include "SlaveMessages.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Target/Process.h"
+
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+DebugDriverThread *DebugDriverThread::m_instance = NULL;
+
+DebugDriverThread::DebugDriverThread()
+{
+    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);
+}
+
+DebugDriverThread::~DebugDriverThread()
+{
+}
+
+void
+DebugDriverThread::Initialize()
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+    if (log)
+        log->Printf("DebugDriverThread::Initialize");
+
+    m_instance = new DebugDriverThread();
+}
+
+void
+DebugDriverThread::Teardown()
+{
+    m_instance->Shutdown();
+
+    delete m_instance;
+    m_instance = nullptr;
+}
+
+void
+DebugDriverThread::Shutdown()
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
+    if (log)
+        log->Printf("DebugDriverThread::Shutdown");
+
+    if (!m_shutdown_event)
+        return;
+    ::SetEvent(m_shutdown_event);
+    m_monitor_thread.Join(nullptr);
+
+    ::CloseHandle(m_shutdown_event);
+    ::CloseHandle(m_monitor_event);
+    ::CloseHandle(m_monitor_pipe_read);
+    ::CloseHandle(m_monitor_pipe_write);
+
+    m_shutdown_event = nullptr;
+    m_monitor_event = nullptr;
+    m_monitor_pipe_read = nullptr;
+    m_monitor_pipe_write = nullptr;
+}
+
+DebugDriverThread &
+DebugDriverThread::GetInstance()
+{
+    return *m_instance;
+}
+
+void
+DebugDriverThread::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 *
+DebugDriverThread::HandleMonitorMessage(const DebugMonitorMessage *message)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+    switch (message->GetMessageType())
+    {
+        case MonitorMessageType::eLaunchProcess:
+        {
+            const auto *launch_message = static_cast<const LaunchProcessMessage *>(message);
+            return HandleMonitorMessage(launch_message);
+        }
+        default:
+            if (log)
+                log->Printf("DebugDriverThread received unknown message type %d.", message->GetMessageType());
+            return nullptr;
+    }
+}
+
+const LaunchProcessMessageResult *
+DebugDriverThread::HandleMonitorMessage(const LaunchProcessMessage *launch_message)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    const char *exe = launch_message->GetLaunchInfo().GetExecutableFile().GetPath().c_str();
+    if (log)
+        log->Printf("DebugDriverThread launching process '%s'.", exe);
+
+    // Create a DebugOneProcessThread which will do the actual creation and enter a debug loop on
+    // a background thread, only returning after the process has been created on the background
+    // thread.
+    std::shared_ptr<DebugOneProcessThread> slave(new DebugOneProcessThread(m_monitor_thread));
+    const LaunchProcessMessageResult *result = slave->DebugLaunch(launch_message);
+    if (result && result->GetError().Success())
+    {
+        if (log)
+            log->Printf("DebugDriverThread launched process '%s' with PID %d.", exe, result->GetProcess().GetProcessId());
+        m_debugged_processes.insert(std::make_pair(result->GetProcess().GetProcessId(), slave));
+    }
+    else
+    {
+        if (log)
+            log->Printf("An error occured launching process '%s' -- %s.", exe, result->GetError().AsCString());
+    }
+    return result;
+}
+
+void
+DebugDriverThread::HandleSlaveEvent(const SlaveMessageProcessExited &message)
+{
+    lldb::pid_t pid = message.GetProcess().GetProcessId();
+
+    m_debugged_processes.erase(pid);
+
+    Process::SetProcessExitStatus(nullptr, pid, true, 0, message.GetExitCode());
+}
+
+void
+DebugDriverThread::HandleSlaveEvent(const SlaveMessageRipEvent &message)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+    lldb::pid_t pid = message.GetProcess().GetProcessId();
+    m_debugged_processes.erase(pid);
+
+    if (log)
+    {
+        log->Printf("An error was encountered while debugging process %d.  Debugging has been terminated.  Error = s.", pid,
+                    message.GetError().AsCString());
+    }
+}
+
+bool
+DebugDriverThread::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
+DebugDriverThread::MonitorThread(void *data)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    if (log)
+        log->Printf("ProcessWindows DebugDriverThread starting up.");
+
+    DebugDriverThread *monitor_thread = static_cast<DebugDriverThread *>(data);
+    const int kMonitorEventIndex = 0;
+    const int kShutdownEventIndex = 1;
+
+    Error error;
+    HANDLE events[kShutdownEventIndex + 1];
+    events[kMonitorEventIndex] = monitor_thread->m_monitor_event;
+    events[kShutdownEventIndex] = monitor_thread->m_shutdown_event;
+
+    while (true)
+    {
+        bool exit = false;
+        // See if any new processes are ready for debug monitoring.
+        DWORD result = WaitForMultipleObjectsEx(llvm::array_lengthof(events), events, FALSE, 1000, TRUE);
+        switch (result)
+        {
+            case WAIT_OBJECT_0 + kMonitorEventIndex:
+                // LLDB is telling us to do something.  Process pending messages in our queue.
+                monitor_thread->ProcessMonitorMessages();
+                break;
+            case WAIT_OBJECT_0 + kShutdownEventIndex:
+                error.SetErrorString("Shutdown event received.");
+                exit = true;
+                break;
+            case WAIT_TIMEOUT:
+            case WAIT_IO_COMPLETION:
+                break;
+            default:
+                error.SetError(GetLastError(), eErrorTypeWin32);
+                exit = true;
+                break;
+        }
+        if (exit)
+            break;
+    }
+
+    if (log)
+        log->Printf("ProcessWindows Debug monitor thread exiting.  %s", error.AsCString());
+    return 0;
+}

Added: lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.h?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugDriverThread.h Mon Nov  3 18:00:12 2014
@@ -0,0 +1,79 @@
+//===-- DebugDriverThread.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_DebugDriverThread_H_
+#define liblldb_Plugins_Process_Windows_DebugDriverThread_H_
+
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-types.h"
+
+#include <map>
+
+class ProcessWindows;
+
+namespace lldb_private
+{
+class DebugMonitorMessage;
+class DebugMonitorMessageResult;
+class DebugOneProcessThread;
+class LaunchProcessMessage;
+class LaunchProcessMessageResult;
+
+class SlaveMessageProcessExited;
+class SlaveMessageRipEvent;
+
+//----------------------------------------------------------------------
+// DebugDriverThread
+//
+// Runs a background thread that pumps a queue from the application to tell the
+// debugger to do different things like launching processes, attaching to
+// processes, etc.
+//----------------------------------------------------------------------
+class DebugDriverThread
+{
+    friend class DebugOneProcessThread;
+
+  public:
+    virtual ~DebugDriverThread();
+
+    static void Initialize();
+    static void Teardown();
+    static DebugDriverThread &GetInstance();
+
+    void PostDebugMessage(const DebugMonitorMessage *message);
+
+  private:
+    DebugDriverThread();
+
+    void Shutdown();
+
+    bool ProcessMonitorMessages();
+    const DebugMonitorMessageResult *HandleMonitorMessage(const DebugMonitorMessage *message);
+    const LaunchProcessMessageResult *HandleMonitorMessage(const LaunchProcessMessage *launch_message);
+
+    // Slave message handlers.  These are invoked by the
+    void HandleSlaveEvent(const SlaveMessageProcessExited &message);
+    void HandleSlaveEvent(const SlaveMessageRipEvent &message);
+
+    static DebugDriverThread *m_instance;
+
+    std::map<lldb::pid_t, std::shared_ptr<DebugOneProcessThread>> 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

Added: lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp Mon Nov  3 18:00:12 2014
@@ -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;
+}

Added: lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.h?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessageResults.h Mon Nov  3 18:00:12 2014
@@ -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:
+    explicit 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

Added: lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.cpp?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.cpp Mon Nov  3 18:00:12 2014
@@ -0,0 +1,62 @@
+//===-- 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, lldb::ProcessSP process_plugin)
+    : DebugMonitorMessage(MonitorMessageType::eLaunchProcess)
+    , m_launch_info(launch_info)
+    , m_process_plugin(process_plugin)
+{
+}
+
+LaunchProcessMessage *
+LaunchProcessMessage::Create(const ProcessLaunchInfo &launch_info, lldb::ProcessSP process_plugin)
+{
+    return new LaunchProcessMessage(launch_info, process_plugin);
+}

Added: lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.h?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugMonitorMessages.h Mon Nov  3 18:00:12 2014
@@ -0,0 +1,86 @@
+//===-- 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/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:
+    explicit 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, lldb::ProcessSP m_process_plugin);
+    const ProcessLaunchInfo &
+    GetLaunchInfo() const
+    {
+        return m_launch_info;
+    }
+
+    lldb::ProcessSP
+    GetProcessPlugin() const
+    {
+        return m_process_plugin;
+    }
+
+  private:
+    LaunchProcessMessage(const ProcessLaunchInfo &launch_info, lldb::ProcessSP m_process_plugin);
+
+    const ProcessLaunchInfo &m_launch_info;
+    lldb::ProcessSP m_process_plugin;
+};
+}
+
+#endif

Added: lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.cpp?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.cpp Mon Nov  3 18:00:12 2014
@@ -0,0 +1,227 @@
+//===-- DebugDriverThread.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugDriverThread.h"
+#include "DebugOneProcessThread.h"
+#include "DebugMonitorMessages.h"
+#include "DebugMonitorMessageResults.h"
+#include "SlaveMessages.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/ThisThread.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/ProcessLauncherWindows.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace
+{
+struct DebugLaunchContext
+{
+    DebugOneProcessThread *instance;
+    const LaunchProcessMessage *launch;
+};
+}
+
+DebugOneProcessThread::DebugOneProcessThread(HostThread driver_thread)
+    : m_driver_thread(driver_thread)
+{
+    m_launch_predicate.SetValue(nullptr, eBroadcastNever);
+}
+
+DebugOneProcessThread::~DebugOneProcessThread()
+{
+}
+
+const LaunchProcessMessageResult *
+DebugOneProcessThread::DebugLaunch(const LaunchProcessMessage *message)
+{
+    Error error;
+    const LaunchProcessMessageResult *result = nullptr;
+    DebugLaunchContext context;
+    context.instance = this;
+    context.launch = message;
+
+    HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]", DebugLaunchThread, &context, &error));
+    if (error.Success())
+        m_launch_predicate.WaitForValueNotEqualTo(nullptr, result);
+
+    return result;
+}
+
+lldb::thread_result_t
+DebugOneProcessThread::DebugLaunchThread(void *data)
+{
+    DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
+    DebugOneProcessThread *thread = context->instance;
+    return thread->DebugLaunchThread(context->launch);
+}
+
+lldb::thread_result_t
+DebugOneProcessThread::DebugLaunchThread(const LaunchProcessMessage *message)
+{
+    // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
+    // thread routine has exited.
+    std::shared_ptr<DebugOneProcessThread> this_ref(shared_from_this());
+    Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+    Error error;
+    ProcessLauncherWindows launcher;
+
+    m_process_plugin = message->GetProcessPlugin();
+    m_process = launcher.LaunchProcess(message->GetLaunchInfo(), error);
+
+    std::string thread_name;
+    llvm::raw_string_ostream name_stream(thread_name);
+    name_stream << "lldb.plugin.process-windows.slave[" << m_process.GetProcessId() << "]";
+    name_stream.flush();
+    ThisThread::SetName(thread_name.c_str());
+
+    LaunchProcessMessageResult *result = LaunchProcessMessageResult::Create(message);
+    result->SetError(error);
+    result->SetProcess(m_process);
+    m_launch_predicate.SetValue(result, eBroadcastAlways);
+
+    DebugLoop();
+    if (log)
+        log->Printf("Debug monitor thread '%s' exiting.", thread_name.c_str());
+
+    return 0;
+}
+
+void
+DebugOneProcessThread::DebugLoop()
+{
+    DEBUG_EVENT dbe = {0};
+    bool exit = false;
+    while (!exit && WaitForDebugEvent(&dbe, INFINITE))
+    {
+        DWORD continue_status = DBG_CONTINUE;
+        switch (dbe.dwDebugEventCode)
+        {
+            case EXCEPTION_DEBUG_EVENT:
+                continue_status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
+                break;
+            case CREATE_THREAD_DEBUG_EVENT:
+                continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
+                break;
+            case CREATE_PROCESS_DEBUG_EVENT:
+                continue_status = HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
+                break;
+            case EXIT_THREAD_DEBUG_EVENT:
+                continue_status = HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
+                break;
+            case EXIT_PROCESS_DEBUG_EVENT:
+                continue_status = HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
+                exit = true;
+                break;
+            case LOAD_DLL_DEBUG_EVENT:
+                continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
+                break;
+            case UNLOAD_DLL_DEBUG_EVENT:
+                continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
+                break;
+            case OUTPUT_DEBUG_STRING_EVENT:
+                continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
+                break;
+            case RIP_EVENT:
+                continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
+                if (dbe.u.RipInfo.dwType == SLE_ERROR)
+                    exit = true;
+                break;
+        }
+
+        ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
+    }
+}
+
+DWORD
+DebugOneProcessThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
+{
+    HANDLE driver = m_driver_thread.GetNativeThread().GetSystemHandle();
+    SlaveMessageProcessExited *message = new SlaveMessageProcessExited(m_process, info.dwExitCode);
+
+    QueueUserAPC(NotifySlaveProcessExited, driver, reinterpret_cast<ULONG_PTR>(message));
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
+{
+    return DBG_CONTINUE;
+}
+
+DWORD
+DebugOneProcessThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
+{
+    HANDLE driver = m_driver_thread.GetNativeThread().GetSystemHandle();
+    Error error(info.dwError, eErrorTypeWin32);
+    SlaveMessageRipEvent *message = new SlaveMessageRipEvent(m_process, error, info.dwType);
+
+    QueueUserAPC(NotifySlaveRipEvent, driver, reinterpret_cast<ULONG_PTR>(message));
+    return DBG_CONTINUE;
+}
+
+void
+DebugOneProcessThread::NotifySlaveProcessExited(ULONG_PTR message)
+{
+    SlaveMessageProcessExited *slave_message = reinterpret_cast<SlaveMessageProcessExited *>(message);
+    DebugDriverThread::GetInstance().HandleSlaveEvent(*slave_message);
+    delete slave_message;
+}
+
+void
+DebugOneProcessThread::NotifySlaveRipEvent(ULONG_PTR message)
+{
+    SlaveMessageRipEvent *slave_message = reinterpret_cast<SlaveMessageRipEvent *>(message);
+    DebugDriverThread::GetInstance().HandleSlaveEvent(*slave_message);
+    delete slave_message;
+}

Added: lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.h?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugOneProcessThread.h Mon Nov  3 18:00:12 2014
@@ -0,0 +1,63 @@
+//===-- DebugOneProcessThread.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_DebugOneProcessThread_H_
+#define liblldb_Plugins_Process_Windows_DebugOneProcessThread_H_
+
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/windows/windows.h"
+
+namespace lldb_private
+{
+class LaunchProcessMessage;
+class LaunchProcessMessageResult;
+
+//----------------------------------------------------------------------
+// DebugOneProcessThread
+//
+// Debugs a single process, notifying the process plugin and/or the debugger
+// driver thread as appropriate when interesting things occur.
+//----------------------------------------------------------------------
+class DebugOneProcessThread : public std::enable_shared_from_this<DebugOneProcessThread>
+{
+  public:
+    DebugOneProcessThread(HostThread driver_thread);
+    virtual ~DebugOneProcessThread();
+
+    const LaunchProcessMessageResult *DebugLaunch(const LaunchProcessMessage *message);
+
+  private:
+    void DebugLoop();
+    DWORD HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
+    DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
+    DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
+
+    static void __stdcall NotifySlaveProcessExited(ULONG_PTR message);
+    static void __stdcall NotifySlaveRipEvent(ULONG_PTR message);
+
+    // The main debug driver thread which is controlling this slave.
+    lldb_private::HostThread m_driver_thread;
+    Predicate<const LaunchProcessMessageResult *> m_launch_predicate;
+    lldb::ProcessSP m_process_plugin;
+    HostProcess m_process;
+
+    static lldb::thread_result_t DebugLaunchThread(void *data);
+    lldb::thread_result_t DebugLaunchThread(const LaunchProcessMessage *message);
+};
+}
+
+#endif

Added: lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.cpp?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.cpp Mon Nov  3 18:00:12 2014
@@ -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 "DebugDriverThread.h"
+#include "DebugMonitorMessages.h"
+#include "DebugMonitorMessageResults.h"
+#include "DebugProcessLauncher.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_plugin)
+    : m_process_plugin(process_plugin)
+{
+}
+
+HostProcess
+DebugProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
+{
+    LaunchProcessMessage *message = LaunchProcessMessage::Create(launch_info, m_process_plugin);
+    DebugDriverThread::GetInstance().PostDebugMessage(message);
+    const LaunchProcessMessageResult *result = static_cast<const LaunchProcessMessageResult *>(message->WaitForCompletion());
+    error = result->GetError();
+    HostProcess process = result->GetProcess();
+
+    message->Release();
+    return process;
+}

Added: lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.h?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/DebugProcessLauncher.h Mon Nov  3 18:00:12 2014
@@ -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
+// DebugDriverThread to launch a new process, then waits for a notification from
+// that thread that the launch is complete.
+//----------------------------------------------------------------------
+class DebugProcessLauncher : public ProcessLauncher
+{
+  public:
+    explicit DebugProcessLauncher(lldb::ProcessSP process_plugin);
+    virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error);
+
+  private:
+    lldb::ProcessSP m_process_plugin;
+};
+}
+
+#endif

Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp?rev=221207&r1=221206&r2=221207&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp Mon Nov  3 18:00:12 2014
@@ -11,18 +11,24 @@
 #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/ThreadLauncher.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 "DebugDriverThread.h"
+#include "DebugProcessLauncher.h"
 #include "ProcessWindows.h"
 
 using namespace lldb;
@@ -48,6 +54,7 @@ ProcessWindows::Initialize()
         PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                       GetPluginDescriptionStatic(),
                                       CreateInstance);
+        DebugDriverThread::Initialize();
     }
 }
 
@@ -59,9 +66,14 @@ ProcessWindows::ProcessWindows(Target& t
 {
 }
 
+ProcessWindows::~ProcessWindows()
+{
+}
+
 void
 ProcessWindows::Terminate()
 {
+    DebugDriverThread::Teardown();
 }
 
 lldb_private::ConstString
@@ -89,7 +101,26 @@ Error
 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
+        return Host::LaunchProcess(launch_info);
+
+    if (!result.Success())
+        return result;
+
+    launch_info.SetProcessID(process.GetProcessId());
+    SetID(process.GetProcessId());
+    return result;
 }
 
 Error
@@ -181,4 +212,3 @@ ProcessWindows::CanDebug(Target &target,
         return exe_module_sp->GetFileSpec().Exists();
     return false;
 }
-

Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h?rev=221207&r1=221206&r2=221207&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h Mon Nov  3 18:00:12 2014
@@ -13,13 +13,20 @@
 // C Includes
 
 // C++ Includes
+#include <map>
 #include <queue>
 
 // Other libraries and framework includes
+#include "lldb/Host/HostThread.h"
 #include "lldb/Target/Process.h"
 
 class ProcessMonitor;
 
+namespace lldb_private
+{
+class HostProcess;
+}
+
 class ProcessWindows :
     public lldb_private::Process
 {
@@ -50,6 +57,8 @@ public:
     ProcessWindows(lldb_private::Target& target,
                    lldb_private::Listener &listener);
 
+    ~ProcessWindows();
+
     virtual lldb_private::Error
     DoDetach(bool keep_stopped);
 
@@ -99,11 +108,7 @@ public:
     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_

Added: lldb/trunk/source/Plugins/Process/Windows/SlaveMessages.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/SlaveMessages.h?rev=221207&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/SlaveMessages.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/SlaveMessages.h Mon Nov  3 18:00:12 2014
@@ -0,0 +1,86 @@
+//===-- SlaveMessages.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_SlaveMessages_H_
+#define liblldb_Plugins_Process_Windows_SlaveMessages_H_
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/HostProcess.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+// SlaveMessageBase
+//
+// SlaveMessageBase serves as a base class for all messages which debug slaves
+// can send up to the driver thread to notify it of events related to processes
+// which are being debugged.
+//----------------------------------------------------------------------
+class SlaveMessageBase
+{
+  public:
+    SlaveMessageBase(const HostProcess &process)
+        : m_process(process)
+    {
+    }
+
+    virtual ~SlaveMessageBase() {}
+
+    const HostProcess &
+    GetProcess() const
+    {
+        return m_process;
+    }
+
+  protected:
+    HostProcess m_process;
+};
+
+class SlaveMessageProcessExited : public SlaveMessageBase
+{
+  public:
+    SlaveMessageProcessExited(const HostProcess &process, DWORD exit_code)
+        : SlaveMessageBase(process)
+        , m_exit_code(exit_code)
+    {
+    }
+
+    DWORD
+    GetExitCode() const { return m_exit_code; }
+
+  private:
+    DWORD m_exit_code;
+};
+
+class SlaveMessageRipEvent : public SlaveMessageBase
+{
+  public:
+    SlaveMessageRipEvent(const HostProcess &process, const Error &error, DWORD type)
+        : SlaveMessageBase(process)
+        , m_error(error)
+        , m_type(type)
+    {
+    }
+
+    const Error &
+    GetError() const
+    {
+        return m_error;
+    }
+    DWORD
+    GetType() const { return m_type; }
+
+  private:
+    Error m_error;
+    DWORD m_type;
+};
+}
+
+#endif





More information about the lldb-commits mailing list