include_directories(../Utility)
add_lldb_library(lldbPluginProcessWindows
- DriverMessages.cpp
- DriverMessageResults.cpp
- DebugOneProcessThread.cpp
- DebugProcessLauncher.cpp
- DebugDriverThread.cpp
+ DebuggerThread.cpp
LocalDebugDelegate.cpp
ProcessWindows.cpp
)
+++ /dev/null
-//===-- 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 "DriverMessages.h"
-#include "DriverMessageResults.h"
-#include "DebugOneProcessThread.h"
-#include "ProcessMessages.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_driver_thread = ThreadLauncher::LaunchThread("lldb.plugin.process-windows.driver-thread", DriverThread, this, nullptr);
- m_shutdown_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
- m_driver_message_event = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- ::CreatePipe(&m_driver_pipe_read, &m_driver_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_driver_thread.Join(nullptr);
-
- ::CloseHandle(m_shutdown_event);
- ::CloseHandle(m_driver_message_event);
- ::CloseHandle(m_driver_pipe_read);
- ::CloseHandle(m_driver_pipe_write);
-
- m_shutdown_event = nullptr;
- m_driver_message_event = nullptr;
- m_driver_pipe_read = nullptr;
- m_driver_pipe_write = nullptr;
-}
-
-DebugDriverThread &
-DebugDriverThread::GetInstance()
-{
- return *m_instance;
-}
-
-void
-DebugDriverThread::PostDebugMessage(const DriverMessage *message)
-{
- message->Retain();
- if (!::WriteFile(m_driver_pipe_write, &message, sizeof(message), NULL, NULL))
- {
- message->Release();
- return;
- }
-
- ::SetEvent(m_driver_message_event);
-}
-
-const DriverMessageResult *
-DebugDriverThread::HandleDriverMessage(const DriverMessage *message)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- switch (message->GetMessageType())
- {
- case DriverMessageType::eLaunchProcess:
- {
- const auto *launch_message = static_cast<const DriverLaunchProcessMessage *>(message);
- return HandleDriverMessage(launch_message);
- }
- default:
- if (log)
- log->Printf("DebugDriverThread received unknown message type %d.", message->GetMessageType());
- return nullptr;
- }
-}
-
-const DriverLaunchProcessMessageResult *
-DebugDriverThread::HandleDriverMessage(const DriverLaunchProcessMessage *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.
- DebugMapEntry map_entry;
- map_entry.m_delegate = launch_message->GetDebugDelegate();
- map_entry.m_slave.reset(new DebugOneProcessThread(m_driver_thread));
- const DriverLaunchProcessMessageResult *result = map_entry.m_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(), map_entry));
- }
- else
- {
- if (log)
- log->Printf("An error occured launching process '%s' -- %s.", exe, result->GetError().AsCString());
- }
- return result;
-}
-
-void
-DebugDriverThread::OnProcessLaunched(const ProcessMessageCreateProcess &message)
-{
-}
-
-void
-DebugDriverThread::OnExitProcess(const ProcessMessageExitProcess &message)
-{
- lldb::pid_t pid = message.GetProcess().GetProcessId();
-
- // We invoke the delegate on the DriverThread rather than on the DebugOneProcessThread
- // so that invoking delegates is thread-safe amongst each other. e.g. Two delegate invocations
- // are guaranteed to happen from the same thread. Additionally, this guarantees that the
- // driver thread has a chance to clean up after itself before notifying processes of the debug
- // events, guaranteeing that no races happen whereby a process tries to kick off a new action
- // as a result of some event, but the request for that new action gets picked up by the driver
- // thread before the driver thread gets notified of the state change.
- auto iter = m_debugged_processes.find(pid);
- if (iter != m_debugged_processes.end())
- iter->second.m_delegate->OnExitProcess(message);
-
- m_debugged_processes.erase(iter);
-}
-
-void
-DebugDriverThread::OnDebuggerConnected(const ProcessMessageDebuggerConnected &message)
-{
-}
-
-void
-DebugDriverThread::OnDebugException(const ProcessMessageException &message)
-{
-}
-
-void
-DebugDriverThread::OnCreateThread(const ProcessMessageCreateThread &message)
-{
-}
-
-void
-DebugDriverThread::OnExitThread(const ProcessMessageExitThread &message)
-{
-}
-
-void
-DebugDriverThread::OnLoadDll(const ProcessMessageLoadDll &message)
-{
-}
-
-void
-DebugDriverThread::OnUnloadDll(const ProcessMessageUnloadDll &message)
-{
-}
-
-void
-DebugDriverThread::OnDebugString(const ProcessMessageDebugString &message)
-{
-}
-
-void
-DebugDriverThread::OnDebuggerError(const ProcessMessageDebuggerError &message)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- lldb::pid_t pid = message.GetProcess().GetProcessId();
- auto iter = m_debugged_processes.find(pid);
- if (iter != m_debugged_processes.end())
- iter->second.m_delegate->OnDebuggerError(message);
- m_debugged_processes.erase(iter);
-
- if (log)
- {
- log->Printf("An error was encountered while debugging process %d. Debugging has been terminated. Error = s.", pid,
- message.GetError().AsCString());
- }
-}
-
-bool
-DebugDriverThread::ProcessDriverMessages()
-{
- DWORD bytes_available = 0;
- if (!PeekNamedPipe(m_driver_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(DriverMessage *);
- std::vector<DriverMessage *> messages(count);
- if (!::ReadFile(m_driver_pipe_read, &messages[0], bytes_available, NULL, NULL))
- return false;
-
- for (DriverMessage *message : messages)
- {
- const DriverMessageResult *result = HandleDriverMessage(message);
- message->CompleteMessage(result);
- message->Release();
- }
- return true;
-}
-
-lldb::thread_result_t
-DebugDriverThread::DriverThread(void *data)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("ProcessWindows DebugDriverThread starting up.");
-
- DebugDriverThread *driver_thread = static_cast<DebugDriverThread *>(data);
- const int kDriverMessageEventIndex = 0;
- const int kShutdownEventIndex = 1;
-
- Error error;
- HANDLE events[kShutdownEventIndex + 1];
- events[kDriverMessageEventIndex] = driver_thread->m_driver_message_event;
- events[kShutdownEventIndex] = driver_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 + kDriverMessageEventIndex:
- // LLDB is telling us to do something. Process pending messages in our queue.
- driver_thread->ProcessDriverMessages();
- 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 driver thread exiting. %s", error.AsCString());
- return 0;
-}
+++ /dev/null
-//===-- 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 "ForwardDecl.h"
-#include "IDebugDelegate.h"
-
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/lldb-types.h"
-
-#include <map>
-
-namespace lldb_private
-{
-
-//----------------------------------------------------------------------
-// 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 : public IDebugDelegate
-{
- friend class DebugOneProcessThread;
- struct DebugMapEntry
- {
- DebugDelegateSP m_delegate;
- std::shared_ptr<DebugOneProcessThread> m_slave;
- };
-
- public:
- virtual ~DebugDriverThread();
-
- static void Initialize();
- static void Teardown();
- static DebugDriverThread &GetInstance();
-
- void PostDebugMessage(const DriverMessage *message);
-
- private:
- DebugDriverThread();
-
- void Shutdown();
-
- bool ProcessDriverMessages();
-
- const DriverMessageResult *HandleDriverMessage(const DriverMessage *message);
- const DriverLaunchProcessMessageResult *HandleDriverMessage(const DriverLaunchProcessMessage *launch_message);
-
- // Debug delegate handlers. These are invoked on the driver thread by way of QueueUserAPC as
- // events happen in the inferiors.
- virtual void OnProcessLaunched(const ProcessMessageCreateProcess &message) override;
- virtual void OnExitProcess(const ProcessMessageExitProcess &message) override;
- virtual void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) override;
- virtual void OnDebugException(const ProcessMessageException &message) override;
- virtual void OnCreateThread(const ProcessMessageCreateThread &message) override;
- virtual void OnExitThread(const ProcessMessageExitThread &message) override;
- virtual void OnLoadDll(const ProcessMessageLoadDll &message) override;
- virtual void OnUnloadDll(const ProcessMessageUnloadDll &message) override;
- virtual void OnDebugString(const ProcessMessageDebugString &message) override;
- virtual void OnDebuggerError(const ProcessMessageDebuggerError &message) override;
-
- static DebugDriverThread *m_instance;
-
- std::map<lldb::pid_t, DebugMapEntry> m_debugged_processes;
-
- HANDLE m_driver_message_event;
- HANDLE m_shutdown_event;
- HANDLE m_driver_pipe_read;
- HANDLE m_driver_pipe_write;
- lldb_private::HostThread m_driver_thread;
-
- static lldb::thread_result_t DriverThread(void *data);
-};
-}
-
-#endif
+++ /dev/null
-//===-- 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 "DriverMessages.h"
-#include "DriverMessageResults.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(DebugDelegateSP debug_delegate)
- : m_debug_delegate(debug_delegate)
-{
-}
-
-HostProcess
-DebugProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
-{
- DriverLaunchProcessMessage *message = DriverLaunchProcessMessage::Create(launch_info, m_debug_delegate);
- DebugDriverThread::GetInstance().PostDebugMessage(message);
- const DriverLaunchProcessMessageResult *result = static_cast<const DriverLaunchProcessMessageResult *>(message->WaitForCompletion());
- error = result->GetError();
- HostProcess process = result->GetProcess();
-
- message->Release();
- return process;
-}
+++ /dev/null
-//===-- 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 "ForwardDecl.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(DebugDelegateSP debug_delegate);
- virtual HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error);
-
- private:
- DebugDelegateSP m_debug_delegate;
-};
-}
-
-#endif
-//===-- DebugDriverThread.cpp -----------------------------------*- C++ -*-===//
+//===-- DebuggerThread.DebuggerThread --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#include "DebugDriverThread.h"
-#include "DebugOneProcessThread.h"
-#include "DriverMessages.h"
-#include "DriverMessageResults.h"
+#include "DebuggerThread.h"
+#include "IDebugDelegate.h"
#include "ProcessMessages.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/windows/HostProcessWindows.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/ProcessLauncherWindows.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "llvm/Support/raw_ostream.h"
{
struct DebugLaunchContext
{
- DebugOneProcessThread *instance;
- const DriverLaunchProcessMessage *launch;
+ DebugLaunchContext(DebuggerThread *thread, const ProcessLaunchInfo &launch_info)
+ : m_thread(thread)
+ , m_launch_info(launch_info)
+ {
+ }
+ DebuggerThread *m_thread;
+ ProcessLaunchInfo m_launch_info;
};
}
-DebugOneProcessThread::DebugOneProcessThread(HostThread driver_thread)
- : m_driver_thread(driver_thread)
- , m_pending_create(nullptr)
+DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
+ : m_debug_delegate(debug_delegate)
, m_image_file(nullptr)
+ , m_launched_event(nullptr)
{
- m_launch_predicate.SetValue(nullptr, eBroadcastNever);
+ m_launched_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
}
-DebugOneProcessThread::~DebugOneProcessThread()
+DebuggerThread::~DebuggerThread()
{
+ if (m_launched_event != nullptr)
+ ::CloseHandle(m_launched_event);
}
-const DriverLaunchProcessMessageResult *
-DebugOneProcessThread::DebugLaunch(const DriverLaunchProcessMessage *message)
+HostProcess
+DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
{
Error error;
- const DriverLaunchProcessMessageResult *result = nullptr;
- DebugLaunchContext context;
- context.instance = this;
- context.launch = message;
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]", DebugLaunchThread, &context, &error));
+
+ DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]", DebuggerThreadRoutine, context, &error));
if (error.Success())
- m_launch_predicate.WaitForValueNotEqualTo(nullptr, result);
+ ::WaitForSingleObject(m_launched_event, INFINITE);
- return result;
+ return m_process;
}
lldb::thread_result_t
-DebugOneProcessThread::DebugLaunchThread(void *data)
+DebuggerThread::DebuggerThreadRoutine(void *data)
{
DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
- DebugOneProcessThread *thread = context->instance;
- return thread->DebugLaunchThread(context->launch);
+ lldb::thread_result_t result = context->m_thread->DebuggerThreadRoutine(context->m_launch_info);
+ delete context;
+ return result;
}
lldb::thread_result_t
-DebugOneProcessThread::DebugLaunchThread(const DriverLaunchProcessMessage *message)
+DebuggerThread::DebuggerThreadRoutine(const ProcessLaunchInfo &launch_info)
{
// 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());
+ std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
Error error;
ProcessLauncherWindows launcher;
- HostProcess process(launcher.LaunchProcess(message->GetLaunchInfo(), error));
- // If we couldn't create the process, return the result immediately. Otherwise enter the debug
+ HostProcess process(launcher.LaunchProcess(launch_info, error));
+ // If we couldn't create the process, notify waiters immediately. Otherwise enter the debug
// loop and wait until we get the create process debug notification. Note that if the process
// was created successfully, we can throw away the process handle we got from CreateProcess
// because Windows will give us another (potentially more useful?) handle when it sends us the
// CREATE_PROCESS_DEBUG_EVENT.
if (error.Success())
- {
- m_pending_create = message;
- m_pending_create->Retain();
DebugLoop();
- }
else
- {
- DriverLaunchProcessMessageResult *result = DriverLaunchProcessMessageResult::Create(m_pending_create);
- result->SetError(error);
- result->SetProcess(process);
- m_launch_predicate.SetValue(result, eBroadcastAlways);
- }
+ SetEvent(m_launched_event);
return 0;
}
void
-DebugOneProcessThread::DebugLoop()
+DebuggerThread::DebugLoop()
{
DEBUG_EVENT dbe = {0};
bool exit = false;
}
DWORD
-DebugOneProcessThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
+DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
{
return DBG_CONTINUE;
}
DWORD
-DebugOneProcessThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
+DebuggerThread::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)
+DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
{
std::string thread_name;
llvm::raw_string_ostream name_stream(thread_name);
((HostThreadWindows &)m_main_thread.GetNativeThread()).SetOwnsHandle(false);
m_image_file = info.hFile;
- DriverLaunchProcessMessageResult *result = DriverLaunchProcessMessageResult::Create(m_pending_create);
- result->SetError(Error());
- result->SetProcess(m_process);
- m_launch_predicate.SetValue(result, eBroadcastAlways);
-
- m_pending_create->Release();
- m_pending_create = nullptr;
+ SetEvent(m_launched_event);
return DBG_CONTINUE;
}
DWORD
-DebugOneProcessThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
+DebuggerThread::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)
+DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
{
- HANDLE driver = m_driver_thread.GetNativeThread().GetSystemHandle();
- ProcessMessageExitProcess *message = new ProcessMessageExitProcess(m_process, info.dwExitCode);
-
- QueueUserAPC(NotifySlaveProcessExited, driver, reinterpret_cast<ULONG_PTR>(message));
+ ProcessMessageExitProcess message(m_process, info.dwExitCode);
+ m_debug_delegate->OnExitProcess(message);
m_process = HostProcess();
m_main_thread = HostThread();
}
DWORD
-DebugOneProcessThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
+DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
{
// Windows does not automatically close info.hFile when the DLL is unloaded.
::CloseHandle(info.hFile);
}
DWORD
-DebugOneProcessThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
+DebuggerThread::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)
+DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
{
return DBG_CONTINUE;
}
DWORD
-DebugOneProcessThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
+DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
{
- HANDLE driver = m_driver_thread.GetNativeThread().GetSystemHandle();
Error error(info.dwError, eErrorTypeWin32);
- ProcessMessageDebuggerError *message = new ProcessMessageDebuggerError(m_process, error, info.dwType);
-
- QueueUserAPC(NotifySlaveRipEvent, driver, reinterpret_cast<ULONG_PTR>(message));
+ ProcessMessageDebuggerError message(m_process, error, info.dwType);
+ m_debug_delegate->OnDebuggerError(message);
return DBG_CONTINUE;
}
-
-void
-DebugOneProcessThread::NotifySlaveProcessExited(ULONG_PTR message)
-{
- ProcessMessageExitProcess *slave_message = reinterpret_cast<ProcessMessageExitProcess *>(message);
- DebugDriverThread::GetInstance().OnExitProcess(*slave_message);
- delete slave_message;
-}
-
-void
-DebugOneProcessThread::NotifySlaveRipEvent(ULONG_PTR message)
-{
- ProcessMessageDebuggerError *slave_message = reinterpret_cast<ProcessMessageDebuggerError *>(message);
- DebugDriverThread::GetInstance().OnDebuggerError(*slave_message);
- delete slave_message;
-}
-//===-- DebugOneProcessThread.h ---------------------------------*- C++ -*-===//
+//===-- DebuggerThread.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Plugins_Process_Windows_DebugOneProcessThread_H_
-#define liblldb_Plugins_Process_Windows_DebugOneProcessThread_H_
+#ifndef liblldb_Plugins_Process_Windows_DebuggerThread_H_
+#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
#include "ForwardDecl.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Predicate.h"
#include "lldb/Host/windows/windows.h"
#include <memory>
{
//----------------------------------------------------------------------
-// DebugOneProcessThread
+// DebuggerThread
//
-// Debugs a single process, notifying the process plugin and/or the debugger
-// driver thread as appropriate when interesting things occur.
+// Debugs a single process, notifying listeners as appropriate when interesting
+// things occur.
//----------------------------------------------------------------------
-class DebugOneProcessThread : public std::enable_shared_from_this<DebugOneProcessThread>
+class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
{
public:
- DebugOneProcessThread(HostThread driver_thread);
- virtual ~DebugOneProcessThread();
+ DebuggerThread(DebugDelegateSP debug_delegate);
+ virtual ~DebuggerThread();
- const DriverLaunchProcessMessageResult *DebugLaunch(const DriverLaunchProcessMessage *message);
+ HostProcess DebugLaunch(const ProcessLaunchInfo &launch_info);
private:
void DebugLoop();
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);
+ DebugDelegateSP m_debug_delegate;
- // The main debug driver thread which is controlling this slave.
- HostThread m_driver_thread;
+ HANDLE m_launched_event; // Signalled when the process is finished launching, either
+ // successfully or with an error.
HostProcess m_process; // The process being debugged.
HostThread m_main_thread; // The main thread of the inferior.
HANDLE m_image_file; // The image file of the process being debugged.
- // After we've called CreateProcess, this signals that we're still waiting for the system
- // debug event telling us the process has been created.
- const DriverLaunchProcessMessage *m_pending_create;
-
- Predicate<const DriverLaunchProcessMessageResult *> m_launch_predicate;
-
- static lldb::thread_result_t DebugLaunchThread(void *data);
- lldb::thread_result_t DebugLaunchThread(const DriverLaunchProcessMessage *message);
+ static lldb::thread_result_t DebuggerThreadRoutine(void *data);
+ lldb::thread_result_t DebuggerThreadRoutine(const ProcessLaunchInfo &launch_info);
};
}
+++ /dev/null
-//===-- DriverMessageResults.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DriverMessageResults.h"
-#include "DriverMessages.h"
-
-#include "lldb/Core/Error.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-DriverMessageResult::DriverMessageResult(const DriverMessage *message)
- : m_message(message)
-{
- Retain();
- if (m_message)
- m_message->Retain();
-}
-
-DriverMessageResult::~DriverMessageResult()
-{
- if (m_message)
- m_message->Release();
-}
-
-void
-DriverMessageResult::SetError(const Error &error)
-{
- m_error = error;
-}
-
-DriverLaunchProcessMessageResult::DriverLaunchProcessMessageResult(const DriverLaunchProcessMessage *message)
- : DriverMessageResult(message)
-{
-}
-
-DriverLaunchProcessMessageResult *
-DriverLaunchProcessMessageResult::Create(const DriverLaunchProcessMessage *message)
-{
- return new DriverLaunchProcessMessageResult(message);
-}
-
-void
-DriverLaunchProcessMessageResult::SetProcess(const HostProcess &process)
-{
- m_process = process;
-}
+++ /dev/null
-//===-- DriverMessageResults.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_DriverMessageResults_H_
-#define liblldb_Plugins_Process_Windows_DriverMessageResults_H_
-
-#include "ForwardDecl.h"
-
-#include "lldb/Core/Error.h"
-#include "lldb/Host/HostProcess.h"
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
-namespace lldb_private
-{
-
-class DriverMessageResult : public llvm::ThreadSafeRefCountedBase<DriverMessageResult>
-{
- public:
- virtual ~DriverMessageResult();
-
- const Error &
- GetError() const
- {
- return m_error;
- }
- const DriverMessage *
- GetOriginalMessage() const
- {
- return m_message;
- }
-
- void SetError(const Error &error);
-
- protected:
- explicit DriverMessageResult(const DriverMessage *message);
-
- private:
- Error m_error;
- const DriverMessage *m_message;
-};
-
-class DriverLaunchProcessMessageResult : public DriverMessageResult
-{
- public:
- static DriverLaunchProcessMessageResult *Create(const DriverLaunchProcessMessage *message);
-
- void SetProcess(const HostProcess &process);
- const HostProcess &
- GetProcess() const
- {
- return m_process;
- }
-
- private:
- DriverLaunchProcessMessageResult(const DriverLaunchProcessMessage *message);
-
- HostProcess m_process;
-};
-}
-
-#endif
+++ /dev/null
-//===-- DriverMessages.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DriverMessages.h"
-#include "DriverMessageResults.h"
-
-#include "lldb/Core/Error.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-DriverMessage::DriverMessage(DriverMessageType message_type)
- : m_message_type(message_type)
-{
- Retain();
- m_completion_predicate.SetValue(nullptr, eBroadcastNever);
-}
-
-DriverMessage::~DriverMessage()
-{
- const DriverMessageResult *result = m_completion_predicate.GetValue();
- if (result)
- result->Release();
- m_completion_predicate.SetValue(nullptr, eBroadcastNever);
-}
-
-const DriverMessageResult *
-DriverMessage::WaitForCompletion()
-{
- const DriverMessageResult *result = nullptr;
- m_completion_predicate.WaitForValueNotEqualTo(nullptr, result);
- return result;
-}
-
-void
-DriverMessage::CompleteMessage(const DriverMessageResult *result)
-{
- if (result)
- result->Retain();
- m_completion_predicate.SetValue(result, eBroadcastAlways);
-}
-
-DriverLaunchProcessMessage::DriverLaunchProcessMessage(const ProcessLaunchInfo &launch_info, DebugDelegateSP debug_delegate)
- : DriverMessage(DriverMessageType::eLaunchProcess)
- , m_launch_info(launch_info)
- , m_debug_delegate(debug_delegate)
-{
-}
-
-DriverLaunchProcessMessage *
-DriverLaunchProcessMessage::Create(const ProcessLaunchInfo &launch_info, DebugDelegateSP debug_delegate)
-{
- return new DriverLaunchProcessMessage(launch_info, debug_delegate);
-}
+++ /dev/null
-//===-- DriverMessages.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_DriverMessages_H_
-#define liblldb_Plugins_Process_Windows_DriverMessages_H_
-
-#include "ForwardDecl.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"
-
-namespace lldb_private
-{
-
-class ProcessLaunchInfo;
-
-enum class DriverMessageType
-{
- 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 DriverMessage : public llvm::ThreadSafeRefCountedBase<DriverMessage>
-{
- public:
- virtual ~DriverMessage();
-
- const DriverMessageResult *WaitForCompletion();
- void CompleteMessage(const DriverMessageResult *result);
-
- DriverMessageType
- GetMessageType() const
- {
- return m_message_type;
- }
-
- protected:
- explicit DriverMessage(DriverMessageType message_type);
-
- private:
- Predicate<const DriverMessageResult *> m_completion_predicate;
- DriverMessageType m_message_type;
-};
-
-class DriverLaunchProcessMessage : public DriverMessage
-{
- public:
- static DriverLaunchProcessMessage *Create(const ProcessLaunchInfo &launch_info, DebugDelegateSP debug_delegate);
-
- const ProcessLaunchInfo &
- GetLaunchInfo() const
- {
- return m_launch_info;
- }
-
- DebugDelegateSP
- GetDebugDelegate() const
- {
- return m_debug_delegate;
- }
-
- private:
- DriverLaunchProcessMessage(const ProcessLaunchInfo &launch_info, DebugDelegateSP debug_delegate);
-
- const ProcessLaunchInfo &m_launch_info;
- DebugDelegateSP m_debug_delegate;
-};
-}
-
-#endif
namespace lldb_private
{
-// Driver message forward declarations
-class DriverMessage;
-class DriverLaunchProcessMessage;
-
-// Driver message result forward declarations
-class DriverMessageResult;
-class DriverLaunchProcessMessageResult;
-
class IDebugDelegate;
+class DebuggerThread;
+
// Process message forward declarations.
class ProcessMessageBase;
class ProcessMessageCreateProcess;
class ProcessMessageDebuggerError;
typedef std::shared_ptr<IDebugDelegate> DebugDelegateSP;
+typedef std::unique_ptr<DebuggerThread> DebuggerThreadUP;
}
#endif
\ No newline at end of file
#include "lldb/Target/FileAction.h"
#include "lldb/Target/Target.h"
-#include "DebugDriverThread.h"
-#include "DebugProcessLauncher.h"
+#include "DebuggerThread.h"
#include "LocalDebugDelegate.h"
#include "ProcessMessages.h"
#include "ProcessWindows.h"
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
CreateInstance);
- DebugDriverThread::Initialize();
}
}
void
ProcessWindows::Terminate()
{
- DebugDriverThread::Teardown();
}
lldb_private::ConstString
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.
DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- DebugProcessLauncher launcher(delegate);
- process = launcher.LaunchProcess(launch_info, result);
+ m_debugger.reset(new DebuggerThread(delegate));
+ process = m_debugger->DebugLaunch(launch_info);
}
else
return Host::LaunchProcess(launch_info);
virtual void OnUnloadDll(const lldb_private::ProcessMessageUnloadDll &message) override;
virtual void OnDebugString(const lldb_private::ProcessMessageDebugString &message) override;
virtual void OnDebuggerError(const lldb_private::ProcessMessageDebuggerError &message) override;
+
+ private:
+ lldb_private::DebuggerThreadUP m_debugger;
};
#endif // liblldb_Plugins_Process_Windows_ProcessWindows_H_