55 changes: 55 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugMonitorMessageResults.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
70 changes: 70 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugMonitorMessageResults.h
Original file line number Diff line number Diff line change
@@ -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
62 changes: 62 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugMonitorMessages.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
86 changes: 86 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugMonitorMessages.h
Original file line number Diff line number Diff line change
@@ -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
227 changes: 227 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugOneProcessThread.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
63 changes: 63 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugOneProcessThread.h
Original file line number Diff line number Diff line change
@@ -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
38 changes: 38 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugProcessLauncher.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
40 changes: 40 additions & 0 deletions lldb/source/Plugins/Process/Windows/DebugProcessLauncher.h
Original file line number Diff line number Diff line change
@@ -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
34 changes: 32 additions & 2 deletions lldb/source/Plugins/Process/Windows/ProcessWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -48,6 +54,7 @@ ProcessWindows::Initialize()
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
CreateInstance);
DebugDriverThread::Initialize();
}
}

Expand All @@ -59,9 +66,14 @@ ProcessWindows::ProcessWindows(Target& target, Listener &listener)
{
}

ProcessWindows::~ProcessWindows()
{
}

void
ProcessWindows::Terminate()
{
DebugDriverThread::Teardown();
}

lldb_private::ConstString
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -181,4 +212,3 @@ ProcessWindows::CanDebug(Target &target, bool plugin_specified_by_name)
return exe_module_sp->GetFileSpec().Exists();
return false;
}

15 changes: 10 additions & 5 deletions lldb/source/Plugins/Process/Windows/ProcessWindows.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -50,6 +57,8 @@ class ProcessWindows :
ProcessWindows(lldb_private::Target& target,
lldb_private::Listener &listener);

~ProcessWindows();

virtual lldb_private::Error
DoDetach(bool keep_stopped);

Expand Down Expand Up @@ -99,11 +108,7 @@ class ProcessWindows :
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_
86 changes: 86 additions & 0 deletions lldb/source/Plugins/Process/Windows/SlaveMessages.h
Original file line number Diff line number Diff line change
@@ -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