summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Windows/Live
diff options
context:
space:
mode:
authorKate Stone <katherine.stone@apple.com>2016-09-06 20:57:50 +0000
committerKate Stone <katherine.stone@apple.com>2016-09-06 20:57:50 +0000
commitb9c1b51e45b845debb76d8658edabca70ca56079 (patch)
treedfcb5a13ef2b014202340f47036da383eaee74aa /lldb/source/Plugins/Process/Windows/Live
parentd5aa73376966339caad04013510626ec2e42c760 (diff)
downloadbcm5719-llvm-b9c1b51e45b845debb76d8658edabca70ca56079.tar.gz
bcm5719-llvm-b9c1b51e45b845debb76d8658edabca70ca56079.zip
*** This commit represents a complete reformatting of the LLDB source code
*** to conform to clang-format’s LLVM style. This kind of mass change has *** two obvious implications: Firstly, merging this particular commit into a downstream fork may be a huge effort. Alternatively, it may be worth merging all changes up to this commit, performing the same reformatting operation locally, and then discarding the merge for this particular commit. The commands used to accomplish this reformatting were as follows (with current working directory as the root of the repository): find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} + find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ; The version of clang-format used was 3.9.0, and autopep8 was 1.2.4. Secondly, “blame” style tools will generally point to this commit instead of a meaningful prior commit. There are alternatives available that will attempt to look through this change and find the appropriate prior commit. YMMV. llvm-svn: 280751
Diffstat (limited to 'lldb/source/Plugins/Process/Windows/Live')
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp858
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/DebuggerThread.h139
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h19
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/IDebugDelegate.h30
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp90
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h43
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp1765
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h178
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp153
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h55
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp277
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h32
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp152
-rw-r--r--lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h24
14 files changed, 1879 insertions, 1936 deletions
diff --git a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
index 2823474cbd5..4dcd7894e4d 100644
--- a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
+++ b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
@@ -1,4 +1,5 @@
-//===-- DebuggerThread.DebuggerThread --------------------------------------*- C++ -*-===//
+//===-- DebuggerThread.DebuggerThread --------------------------------------*-
+//C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -21,8 +22,8 @@
#include "lldb/Host/windows/HostProcessWindows.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
@@ -33,517 +34,518 @@
using namespace lldb;
using namespace lldb_private;
-namespace
-{
-struct DebugLaunchContext
-{
- DebugLaunchContext(DebuggerThread *thread, const ProcessLaunchInfo &launch_info)
- : m_thread(thread)
- , m_launch_info(launch_info)
- {
- }
- DebuggerThread *m_thread;
- ProcessLaunchInfo m_launch_info;
+namespace {
+struct DebugLaunchContext {
+ DebugLaunchContext(DebuggerThread *thread,
+ const ProcessLaunchInfo &launch_info)
+ : m_thread(thread), m_launch_info(launch_info) {}
+ DebuggerThread *m_thread;
+ ProcessLaunchInfo m_launch_info;
};
-struct DebugAttachContext
-{
- DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid, const ProcessAttachInfo &attach_info)
- : m_thread(thread)
- , m_pid(pid)
- , m_attach_info(attach_info)
- {
- }
- DebuggerThread *m_thread;
- lldb::pid_t m_pid;
- ProcessAttachInfo m_attach_info;
+struct DebugAttachContext {
+ DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info)
+ : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
+ DebuggerThread *m_thread;
+ lldb::pid_t m_pid;
+ ProcessAttachInfo m_attach_info;
};
}
DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
- : m_debug_delegate(debug_delegate)
- , m_image_file(nullptr)
- , m_debugging_ended_event(nullptr)
- , m_is_shutting_down(false)
- , m_pid_to_detach(0)
- , m_detached(false)
-{
- m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
+ : m_debug_delegate(debug_delegate), m_image_file(nullptr),
+ m_debugging_ended_event(nullptr), m_is_shutting_down(false),
+ m_pid_to_detach(0), m_detached(false) {
+ m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
}
-DebuggerThread::~DebuggerThread()
-{
- ::CloseHandle(m_debugging_ended_event);
-}
+DebuggerThread::~DebuggerThread() { ::CloseHandle(m_debugging_ended_event); }
-Error
-DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
-{
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DebuggerThread::DebugLaunch launching '%s'", launch_info.GetExecutableFile().GetPath().c_str());
+Error DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread::DebugLaunch launching '%s'",
+ launch_info.GetExecutableFile().GetPath().c_str());
- Error error;
- DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
- DebuggerThreadLaunchRoutine, context, &error));
+ Error error;
+ DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
+ context, &error));
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DebugLaunch couldn't launch debugger thread. %s", error.AsCString());
- }
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "DebugLaunch couldn't launch debugger thread. %s",
+ error.AsCString());
+ }
- return error;
+ return error;
}
-Error
-DebuggerThread::DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread::DebugAttach attaching to '%u'", (DWORD)pid);
-
- Error error;
- DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
- DebuggerThreadAttachRoutine, context, &error));
+Error DebuggerThread::DebugAttach(lldb::pid_t pid,
+ const ProcessAttachInfo &attach_info) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread::DebugAttach attaching to '%u'", (DWORD)pid);
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DebugAttach couldn't attach to process '%u'. %s", (DWORD)pid,
- error.AsCString());
- }
+ Error error;
+ DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
+ HostThread slave_thread(ThreadLauncher::LaunchThread(
+ "lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine,
+ context, &error));
- return error;
-}
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "DebugAttach couldn't attach to process '%u'. %s", (DWORD)pid,
+ error.AsCString());
+ }
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadLaunchRoutine(void *data)
-{
- DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
- lldb::thread_result_t result = context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
- delete context;
- return result;
+ return error;
}
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadAttachRoutine(void *data)
-{
- DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
- lldb::thread_result_t result =
- context->m_thread->DebuggerThreadAttachRoutine(context->m_pid, context->m_attach_info);
- delete context;
- return result;
+lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
+ DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
+ lldb::thread_result_t result =
+ context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
+ delete context;
+ return result;
}
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadLaunchRoutine(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<DebuggerThread> this_ref(shared_from_this());
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to launch '%s' on background thread.",
- launch_info.GetExecutableFile().GetPath().c_str());
-
- Error error;
- ProcessLauncherWindows launcher;
- 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())
- DebugLoop();
- else
- m_debug_delegate->OnDebuggerError(error, 0);
-
- return 0;
+lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
+ DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
+ lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
+ context->m_pid, context->m_attach_info);
+ delete context;
+ return result;
}
-lldb::thread_result_t
-DebuggerThread::DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &attach_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<DebuggerThread> this_ref(shared_from_this());
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to process '%u' on background thread.",
- (DWORD)pid);
-
- if (!DebugActiveProcess((DWORD)pid))
- {
- Error error(::GetLastError(), eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, 0);
- return 0;
- }
-
- // The attach was successful, enter the debug loop. From here on out, this is no different than
- // a create process operation, so all the same comments in DebugLaunch should apply from this
- // point out.
+lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
+ 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<DebuggerThread> this_ref(shared_from_this());
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "DebuggerThread preparing to launch '%s' on background thread.",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ Error error;
+ ProcessLauncherWindows launcher;
+ 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())
DebugLoop();
+ else
+ m_debug_delegate->OnDebuggerError(error, 0);
- return 0;
+ return 0;
}
-Error
-DebuggerThread::StopDebugging(bool terminate)
-{
- Error error;
+lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_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<DebuggerThread> this_ref(shared_from_this());
- lldb::pid_t pid = m_process.GetProcessId();
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to "
+ "process '%u' on background thread.",
+ (DWORD)pid);
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging('%s') called (inferior=%I64u).",
- (terminate ? "true" : "false"), pid);
-
- // Set m_is_shutting_down to true if it was false. Return if it was already true.
- bool expected = false;
- if (!m_is_shutting_down.compare_exchange_strong(expected, true))
- return error;
-
- // Make a copy of the process, since the termination sequence will reset
- // DebuggerThread's internal copy and it needs to remain open for the Wait operation.
- HostProcess process_copy = m_process;
- lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
-
- if (terminate)
- {
- // Initiate the termination before continuing the exception, so that the next debug
- // event we get is the exit process event, and not some other event.
- BOOL terminate_suceeded = TerminateProcess(handle, 0);
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging called TerminateProcess(0x%p, 0) (inferior=%I64u), success='%s'",
- handle, pid, (terminate_suceeded ? "true" : "false"));
- }
+ if (!DebugActiveProcess((DWORD)pid)) {
+ Error error(::GetLastError(), eErrorTypeWin32);
+ m_debug_delegate->OnDebuggerError(error, 0);
+ return 0;
+ }
- // If we're stuck waiting for an exception to continue (e.g. the user is at a breakpoint
- // messing around in the debugger), continue it now. But only AFTER calling TerminateProcess
- // to make sure that the very next call to WaitForDebugEvent is an exit process event.
- if (m_active_exception.get())
- {
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
- "StopDebugging masking active exception");
+ // The attach was successful, enter the debug loop. From here on out, this is
+ // no different than
+ // a create process operation, so all the same comments in DebugLaunch should
+ // apply from this
+ // point out.
+ DebugLoop();
- ContinueAsyncException(ExceptionResult::MaskException);
- }
+ return 0;
+}
- if (!terminate)
- {
- // Indicate that we want to detach.
- m_pid_to_detach = GetProcess().GetProcessId();
+Error DebuggerThread::StopDebugging(bool terminate) {
+ Error error;
- // Force a fresh break so that the detach can happen from the debugger thread.
- if (!::DebugBreakProcess(GetProcess().GetNativeProcess().GetSystemHandle()))
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- }
- }
+ lldb::pid_t pid = m_process.GetProcessId();
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging waiting for detach from process %u to complete.", pid);
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging('%s') called (inferior=%I64u).",
+ (terminate ? "true" : "false"), pid);
- DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
- if (wait_result != WAIT_OBJECT_0)
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging WaitForSingleObject(0x%p, 5000) returned %u",
- m_debugging_ended_event, wait_result);
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging detach from process %u completed successfully.", pid);
- }
+ // Set m_is_shutting_down to true if it was false. Return if it was already
+ // true.
+ bool expected = false;
+ if (!m_is_shutting_down.compare_exchange_strong(expected, true))
+ return error;
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "StopDebugging encountered an error while trying to stop process %u. %s",
- pid, error.AsCString());
+ // Make a copy of the process, since the termination sequence will reset
+ // DebuggerThread's internal copy and it needs to remain open for the Wait
+ // operation.
+ HostProcess process_copy = m_process;
+ lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
+
+ if (terminate) {
+ // Initiate the termination before continuing the exception, so that the
+ // next debug
+ // event we get is the exit process event, and not some other event.
+ BOOL terminate_suceeded = TerminateProcess(handle, 0);
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging called "
+ "TerminateProcess(0x%p, 0) "
+ "(inferior=%I64u), success='%s'",
+ handle, pid, (terminate_suceeded ? "true" : "false"));
+ }
+
+ // If we're stuck waiting for an exception to continue (e.g. the user is at a
+ // breakpoint
+ // messing around in the debugger), continue it now. But only AFTER calling
+ // TerminateProcess
+ // to make sure that the very next call to WaitForDebugEvent is an exit
+ // process event.
+ if (m_active_exception.get()) {
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_EXCEPTION,
+ "StopDebugging masking active exception");
+
+ ContinueAsyncException(ExceptionResult::MaskException);
+ }
+
+ if (!terminate) {
+ // Indicate that we want to detach.
+ m_pid_to_detach = GetProcess().GetProcessId();
+
+ // Force a fresh break so that the detach can happen from the debugger
+ // thread.
+ if (!::DebugBreakProcess(
+ GetProcess().GetNativeProcess().GetSystemHandle())) {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
}
- return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging waiting for detach from process %u to complete.",
+ pid);
+
+ DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
+ if (wait_result != WAIT_OBJECT_0) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging WaitForSingleObject(0x%p, 5000) returned %u",
+ m_debugging_ended_event, wait_result);
+ } else {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "StopDebugging detach from process %u completed successfully.",
+ pid);
+ }
+
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging encountered an error "
+ "while trying to stop process %u. %s",
+ pid, error.AsCString());
+ }
+ return error;
}
-void
-DebuggerThread::ContinueAsyncException(ExceptionResult result)
-{
- if (!m_active_exception.get())
- return;
+void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
+ if (!m_active_exception.get())
+ return;
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
- "ContinueAsyncException called for inferior process %I64u, broadcasting.",
- m_process.GetProcessId());
+ WINLOG_IFANY(
+ WINDOWS_LOG_PROCESS | WINDOWS_LOG_EXCEPTION,
+ "ContinueAsyncException called for inferior process %I64u, broadcasting.",
+ m_process.GetProcessId());
- m_active_exception.reset();
- m_exception_pred.SetValue(result, eBroadcastAlways);
+ m_active_exception.reset();
+ m_exception_pred.SetValue(result, eBroadcastAlways);
}
-void
-DebuggerThread::FreeProcessHandles()
-{
- m_process = HostProcess();
- m_main_thread = HostThread();
- if (m_image_file)
- {
- ::CloseHandle(m_image_file);
- m_image_file = nullptr;
- }
+void DebuggerThread::FreeProcessHandles() {
+ m_process = HostProcess();
+ m_main_thread = HostThread();
+ if (m_image_file) {
+ ::CloseHandle(m_image_file);
+ m_image_file = nullptr;
+ }
}
-void
-DebuggerThread::DebugLoop()
-{
- DEBUG_EVENT dbe = {0};
- bool should_debug = true;
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
- while (should_debug)
- {
- WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
- BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
- if (wait_result)
- {
- DWORD continue_status = DBG_CONTINUE;
- switch (dbe.dwDebugEventCode)
- {
- case EXCEPTION_DEBUG_EVENT:
- {
- ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
-
- if (status == ExceptionResult::MaskException)
- continue_status = DBG_CONTINUE;
- else if (status == ExceptionResult::SendToApplication)
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
-
- 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);
- should_debug = false;
- 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)
- should_debug = false;
- break;
- }
-
- WINLOGD_IFALL(WINDOWS_LOG_EVENT, "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
- dbe.dwProcessId, dbe.dwThreadId, continue_status, ::GetCurrentThreadId());
-
- ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
-
- if (m_detached)
- {
- should_debug = false;
- }
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
- ::GetCurrentThreadId(), ::GetLastError());
-
- should_debug = false;
- }
+void DebuggerThread::DebugLoop() {
+ DEBUG_EVENT dbe = {0};
+ bool should_debug = true;
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
+ while (should_debug) {
+ WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
+ BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
+ if (wait_result) {
+ DWORD continue_status = DBG_CONTINUE;
+ switch (dbe.dwDebugEventCode) {
+ case EXCEPTION_DEBUG_EVENT: {
+ ExceptionResult status =
+ HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
+
+ if (status == ExceptionResult::MaskException)
+ continue_status = DBG_CONTINUE;
+ else if (status == ExceptionResult::SendToApplication)
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
+
+ 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);
+ should_debug = false;
+ 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)
+ should_debug = false;
+ break;
+ }
+
+ WINLOGD_IFALL(
+ WINDOWS_LOG_EVENT,
+ "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
+ dbe.dwProcessId, dbe.dwThreadId, continue_status,
+ ::GetCurrentThreadId());
+
+ ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
+
+ if (m_detached) {
+ should_debug = false;
+ }
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_EVENT,
+ "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
+ ::GetCurrentThreadId(), ::GetLastError());
+
+ should_debug = false;
}
- FreeProcessHandles();
+ }
+ FreeProcessHandles();
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
- SetEvent(m_debugging_ended_event);
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
+ SetEvent(m_debugging_ended_event);
}
ExceptionResult
-DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
-{
- if (m_is_shutting_down)
- {
- // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic exception that
- // we use simply to wake up the DebuggerThread so that we can close out the debug loop.
- if (m_pid_to_detach != 0 && info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
- {
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS,
- "Breakpoint exception is cue to detach from process 0x%x",
- m_pid_to_detach.load());
- ::DebugActiveProcessStop(m_pid_to_detach);
- m_detached = true;
- }
-
- // Don't perform any blocking operations while we're shutting down. That will
- // cause TerminateProcess -> WaitForSingleObject to time out.
- return ExceptionResult::SendToApplication;
+DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
+ DWORD thread_id) {
+ if (m_is_shutting_down) {
+ // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
+ // exception that
+ // we use simply to wake up the DebuggerThread so that we can close out the
+ // debug loop.
+ if (m_pid_to_detach != 0 &&
+ info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION |
+ WINDOWS_LOG_PROCESS,
+ "Breakpoint exception is cue to detach from process 0x%x",
+ m_pid_to_detach.load());
+ ::DebugActiveProcessStop(m_pid_to_detach);
+ m_detached = true;
}
- bool first_chance = (info.dwFirstChance != 0);
+ // Don't perform any blocking operations while we're shutting down. That
+ // will
+ // cause TerminateProcess -> WaitForSingleObject to time out.
+ return ExceptionResult::SendToApplication;
+ }
+
+ bool first_chance = (info.dwFirstChance != 0);
- m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
- "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
- first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
+ m_active_exception.reset(
+ new ExceptionRecord(info.ExceptionRecord, thread_id));
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "HandleExceptionEvent encountered %s chance exception 0x%x on "
+ "thread 0x%x",
+ first_chance ? "first" : "second",
+ info.ExceptionRecord.ExceptionCode, thread_id);
- ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
- *m_active_exception);
- m_exception_pred.SetValue(result, eBroadcastNever);
+ ExceptionResult result =
+ m_debug_delegate->OnDebugException(first_chance, *m_active_exception);
+ m_exception_pred.SetValue(result, eBroadcastNever);
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
- "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred != BreakInDebugger");
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred "
+ "!= BreakInDebugger");
- m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger, result);
+ m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger,
+ result);
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
- "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
- m_exception_pred.GetValue());
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
+ "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
+ m_exception_pred.GetValue());
- return result;
+ return result;
}
DWORD
-DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
- thread_id, m_process.GetProcessId());
- HostThread thread(info.hThread);
- thread.GetNativeThread().SetOwnsHandle(false);
- m_debug_delegate->OnCreateThread(thread);
- return DBG_CONTINUE;
+DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
+ thread_id, m_process.GetProcessId());
+ HostThread thread(info.hThread);
+ thread.GetNativeThread().SetOwnsHandle(false);
+ m_debug_delegate->OnCreateThread(thread);
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
-{
- uint32_t process_id = ::GetProcessId(info.hProcess);
-
- WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
-
- std::string thread_name;
- llvm::raw_string_ostream name_stream(thread_name);
- name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
- name_stream.flush();
- ThisThread::SetName(thread_name.c_str());
-
- // info.hProcess and info.hThread are closed automatically by Windows when
- // EXIT_PROCESS_DEBUG_EVENT is received.
- m_process = HostProcess(info.hProcess);
- ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
- m_main_thread = HostThread(info.hThread);
- m_main_thread.GetNativeThread().SetOwnsHandle(false);
- m_image_file = info.hFile;
-
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
- m_debug_delegate->OnDebuggerConnected(load_addr);
-
- return DBG_CONTINUE;
+DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id) {
+ uint32_t process_id = ::GetProcessId(info.hProcess);
+
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS,
+ "HandleCreateProcessEvent process %u spawned", process_id);
+
+ std::string thread_name;
+ llvm::raw_string_ostream name_stream(thread_name);
+ name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
+ name_stream.flush();
+ ThisThread::SetName(thread_name.c_str());
+
+ // info.hProcess and info.hThread are closed automatically by Windows when
+ // EXIT_PROCESS_DEBUG_EVENT is received.
+ m_process = HostProcess(info.hProcess);
+ ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
+ m_main_thread = HostThread(info.hThread);
+ m_main_thread.GetNativeThread().SetOwnsHandle(false);
+ m_image_file = info.hFile;
+
+ lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
+ m_debug_delegate->OnDebuggerConnected(load_addr);
+
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
- thread_id, info.dwExitCode, m_process.GetProcessId());
- m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
- return DBG_CONTINUE;
+DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(
+ WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
+ thread_id, info.dwExitCode, m_process.GetProcessId());
+ m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
- "HandleExitProcessEvent process %I64u exited with code %u",
- m_process.GetProcessId(), info.dwExitCode);
+DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD,
+ "HandleExitProcessEvent process %I64u exited with code %u",
+ m_process.GetProcessId(), info.dwExitCode);
- m_debug_delegate->OnExitProcess(info.dwExitCode);
+ m_debug_delegate->OnExitProcess(info.dwExitCode);
- FreeProcessHandles();
- return DBG_CONTINUE;
+ FreeProcessHandles();
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
-{
- if (info.hFile == nullptr)
- {
- // Not sure what this is, so just ignore it.
- WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
- m_process.GetProcessId());
- return DBG_CONTINUE;
- }
-
- std::vector<wchar_t> buffer(1);
- DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
- if (required_size > 0)
- {
- buffer.resize(required_size + 1);
- required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size, VOLUME_NAME_DOS);
- std::string path_str_utf8;
- llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
- llvm::StringRef path_str = path_str_utf8;
- const char *path = path_str.data();
- if (path_str.startswith("\\\\?\\"))
- path += 4;
-
- FileSpec file_spec(path, false);
- ModuleSpec module_spec(file_spec);
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
-
- WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
- m_process.GetProcessId(), path, info.lpBaseOfDll);
-
- m_debug_delegate->OnLoadDll(module_spec, load_addr);
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
- m_process.GetProcessId(), ::GetLastError());
- }
- // Windows does not automatically close info.hFile, so we need to do it.
- ::CloseHandle(info.hFile);
+DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id) {
+ if (info.hFile == nullptr) {
+ // Not sure what this is, so just ignore it.
+ WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has "
+ "a NULL file handle, returning...",
+ m_process.GetProcessId());
return DBG_CONTINUE;
+ }
+
+ std::vector<wchar_t> buffer(1);
+ DWORD required_size =
+ GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
+ if (required_size > 0) {
+ buffer.resize(required_size + 1);
+ required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0],
+ required_size, VOLUME_NAME_DOS);
+ std::string path_str_utf8;
+ llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
+ llvm::StringRef path_str = path_str_utf8;
+ const char *path = path_str.data();
+ if (path_str.startswith("\\\\?\\"))
+ path += 4;
+
+ FileSpec file_spec(path, false);
+ ModuleSpec module_spec(file_spec);
+ lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
+
+ WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL "
+ "'%s' loaded at address 0x%p...",
+ m_process.GetProcessId(), path, info.lpBaseOfDll);
+
+ m_debug_delegate->OnLoadDll(module_spec, load_addr);
+ } else {
+ WINERR_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent Error "
+ "%u occurred calling "
+ "GetFinalPathNameByHandle",
+ m_process.GetProcessId(), ::GetLastError());
+ }
+ // Windows does not automatically close info.hFile, so we need to do it.
+ ::CloseHandle(info.hFile);
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
-{
- WINLOG_IFALL(WINDOWS_LOG_EVENT,
- "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
- m_process.GetProcessId(), info.lpBaseOfDll);
-
- m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
- return DBG_CONTINUE;
+DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
+ DWORD thread_id) {
+ WINLOG_IFALL(WINDOWS_LOG_EVENT,
+ "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
+ m_process.GetProcessId(), info.lpBaseOfDll);
+
+ m_debug_delegate->OnUnloadDll(
+ reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
-{
- return DBG_CONTINUE;
+DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
+ DWORD thread_id) {
+ return DBG_CONTINUE;
}
DWORD
-DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
-{
- WINERR_IFALL(WINDOWS_LOG_EVENT,
- "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
- info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
+DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
+ WINERR_IFALL(WINDOWS_LOG_EVENT, "HandleRipEvent encountered error %u "
+ "(type=%u) in process %I64u thread %u",
+ info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
- Error error(info.dwError, eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, info.dwType);
+ Error error(info.dwError, eErrorTypeWin32);
+ m_debug_delegate->OnDebuggerError(error, info.dwType);
- return DBG_CONTINUE;
+ return DBG_CONTINUE;
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.h b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.h
index 6a261941395..fb536b4cc11 100644
--- a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.h
+++ b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.h
@@ -19,8 +19,7 @@
#include "lldb/Host/Predicate.h"
#include "lldb/Host/windows/windows.h"
-namespace lldb_private
-{
+namespace lldb_private {
//----------------------------------------------------------------------
// DebuggerThread
@@ -28,72 +27,76 @@ namespace lldb_private
// Debugs a single process, notifying listeners as appropriate when interesting
// things occur.
//----------------------------------------------------------------------
-class DebuggerThread : public std::enable_shared_from_this<DebuggerThread>
-{
- public:
- DebuggerThread(DebugDelegateSP debug_delegate);
- virtual ~DebuggerThread();
-
- Error DebugLaunch(const ProcessLaunchInfo &launch_info);
- Error DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
-
- HostProcess
- GetProcess() const
- {
- return m_process;
- }
- HostThread
- GetMainThread() const
- {
- return m_main_thread;
- }
- std::weak_ptr<ExceptionRecord>
- GetActiveException()
- {
- return m_active_exception;
- }
-
- Error StopDebugging(bool terminate);
-
- void ContinueAsyncException(ExceptionResult result);
-
- private:
- void FreeProcessHandles();
- void DebugLoop();
- ExceptionResult 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);
-
- DebugDelegateSP m_debug_delegate;
-
- 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.
-
- ExceptionRecordSP m_active_exception; // The current exception waiting to be handled
-
- Predicate<ExceptionResult> m_exception_pred; // A predicate which gets signalled when an exception
- // is finished processing and the debug loop can be
- // continued.
-
- HANDLE m_debugging_ended_event; // An event which gets signalled by the debugger thread when it
- // exits the debugger loop and is detached from the inferior.
-
- std::atomic<DWORD> m_pid_to_detach; // Signals the loop to detach from the process (specified by pid).
- std::atomic<bool> m_is_shutting_down; // Signals the debug loop to stop processing certain types of
- // events that block shutdown.
- bool m_detached; // Indicates we've detached from the inferior process and the debug loop can exit.
-
- static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
- lldb::thread_result_t DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
- static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
- lldb::thread_result_t DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &launch_info);
+class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
+public:
+ DebuggerThread(DebugDelegateSP debug_delegate);
+ virtual ~DebuggerThread();
+
+ Error DebugLaunch(const ProcessLaunchInfo &launch_info);
+ Error DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
+
+ HostProcess GetProcess() const { return m_process; }
+ HostThread GetMainThread() const { return m_main_thread; }
+ std::weak_ptr<ExceptionRecord> GetActiveException() {
+ return m_active_exception;
+ }
+
+ Error StopDebugging(bool terminate);
+
+ void ContinueAsyncException(ExceptionResult result);
+
+private:
+ void FreeProcessHandles();
+ void DebugLoop();
+ ExceptionResult 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);
+
+ DebugDelegateSP m_debug_delegate;
+
+ 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.
+
+ ExceptionRecordSP
+ m_active_exception; // The current exception waiting to be handled
+
+ Predicate<ExceptionResult>
+ m_exception_pred; // A predicate which gets signalled when an exception
+ // is finished processing and the debug loop can be
+ // continued.
+
+ HANDLE m_debugging_ended_event; // An event which gets signalled by the
+ // debugger thread when it
+ // exits the debugger loop and is detached from the inferior.
+
+ std::atomic<DWORD> m_pid_to_detach; // Signals the loop to detach from the
+ // process (specified by pid).
+ std::atomic<bool> m_is_shutting_down; // Signals the debug loop to stop
+ // processing certain types of
+ // events that block shutdown.
+ bool m_detached; // Indicates we've detached from the inferior process and the
+ // debug loop can exit.
+
+ static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
+ lldb::thread_result_t
+ DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
+ static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
+ lldb::thread_result_t
+ DebuggerThreadAttachRoutine(lldb::pid_t pid,
+ const ProcessAttachInfo &launch_info);
};
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h b/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h
index a782597555e..cfe1b79cee1 100644
--- a/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h
+++ b/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h
@@ -14,17 +14,18 @@
// ExceptionResult is returned by the debug delegate to specify how it processed
// the exception.
-enum class ExceptionResult
-{
- BreakInDebugger, // Break in the debugger and give the user a chance to interact with
- // the program before continuing.
- MaskException, // Eat the exception and don't let the application know it occurred.
- SendToApplication // Send the exception to the application to be handled as if there were
- // no debugger attached.
+enum class ExceptionResult {
+ BreakInDebugger, // Break in the debugger and give the user a chance to
+ // interact with
+ // the program before continuing.
+ MaskException, // Eat the exception and don't let the application know it
+ // occurred.
+ SendToApplication // Send the exception to the application to be handled as if
+ // there were
+ // no debugger attached.
};
-namespace lldb_private
-{
+namespace lldb_private {
class ProcessWindows;
diff --git a/lldb/source/Plugins/Process/Windows/Live/IDebugDelegate.h b/lldb/source/Plugins/Process/Windows/Live/IDebugDelegate.h
index 6d864de7ed4..e88e0ada053 100644
--- a/lldb/source/Plugins/Process/Windows/Live/IDebugDelegate.h
+++ b/lldb/source/Plugins/Process/Windows/Live/IDebugDelegate.h
@@ -15,8 +15,7 @@
#include "lldb/lldb-types.h"
#include <string>
-namespace lldb_private
-{
+namespace lldb_private {
class Error;
class HostThread;
@@ -26,20 +25,21 @@ class HostThread;
// IDebugDelegate defines an interface which allows implementors to receive
// notification of events that happen in a debugged process.
//----------------------------------------------------------------------
-class IDebugDelegate
-{
- public:
- virtual ~IDebugDelegate() {}
+class IDebugDelegate {
+public:
+ virtual ~IDebugDelegate() {}
- virtual void OnExitProcess(uint32_t exit_code) = 0;
- virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
- virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) = 0;
- virtual void OnCreateThread(const HostThread &thread) = 0;
- virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
- virtual void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) = 0;
- virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
- virtual void OnDebugString(const std::string &string) = 0;
- virtual void OnDebuggerError(const Error &error, uint32_t type) = 0;
+ virtual void OnExitProcess(uint32_t exit_code) = 0;
+ virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
+ virtual ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) = 0;
+ virtual void OnCreateThread(const HostThread &thread) = 0;
+ virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
+ virtual void OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) = 0;
+ virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
+ virtual void OnDebugString(const std::string &string) = 0;
+ virtual void OnDebuggerError(const Error &error, uint32_t type) = 0;
};
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
index a0ac9725c75..af18999f431 100644
--- a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
+++ b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp
@@ -14,78 +14,60 @@ using namespace lldb;
using namespace lldb_private;
LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
- : m_process(process)
-{
-}
+ : m_process(process) {}
-void
-LocalDebugDelegate::OnExitProcess(uint32_t exit_code)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnExitProcess(exit_code);
+void LocalDebugDelegate::OnExitProcess(uint32_t exit_code) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnExitProcess(exit_code);
}
-void
-LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebuggerConnected(image_base);
+void LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnDebuggerConnected(image_base);
}
ExceptionResult
-LocalDebugDelegate::OnDebugException(bool first_chance, const ExceptionRecord &record)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- return process->OnDebugException(first_chance, record);
- else
- return ExceptionResult::MaskException;
+LocalDebugDelegate::OnDebugException(bool first_chance,
+ const ExceptionRecord &record) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ return process->OnDebugException(first_chance, record);
+ else
+ return ExceptionResult::MaskException;
}
-void
-LocalDebugDelegate::OnCreateThread(const HostThread &thread)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnCreateThread(thread);
+void LocalDebugDelegate::OnCreateThread(const HostThread &thread) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnCreateThread(thread);
}
-void
-LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnExitThread(thread_id, exit_code);
+void LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id,
+ uint32_t exit_code) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnExitThread(thread_id, exit_code);
}
-void
-LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnLoadDll(module_spec, module_addr);
+void LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnLoadDll(module_spec, module_addr);
}
-void
-LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnUnloadDll(module_addr);
+void LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnUnloadDll(module_addr);
}
-void
-LocalDebugDelegate::OnDebugString(const std::string &string)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebugString(string);
+void LocalDebugDelegate::OnDebugString(const std::string &string) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnDebugString(string);
}
-void
-LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type)
-{
- if (ProcessWindowsLiveSP process = GetProcessPointer())
- process->OnDebuggerError(error, type);
+void LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type) {
+ if (ProcessWindowsLiveSP process = GetProcessPointer())
+ process->OnDebuggerError(error, type);
}
-ProcessWindowsLiveSP
-LocalDebugDelegate::GetProcessPointer()
-{
- ProcessSP process = m_process.lock();
- return std::static_pointer_cast<ProcessWindowsLive>(process);
+ProcessWindowsLiveSP LocalDebugDelegate::GetProcessPointer() {
+ ProcessSP process = m_process.lock();
+ return std::static_pointer_cast<ProcessWindowsLive>(process);
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h
index ec2f9418142..17e760c4453 100644
--- a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h
+++ b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h
@@ -16,8 +16,7 @@
#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class ProcessWindowsLive;
typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
@@ -26,9 +25,11 @@ typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
// LocalDebugDelegate
//
// LocalDebugDelegate creates a connection between a ProcessWindowsLive and the
-// debug driver. This serves to decouple ProcessWindowsLive from the debug driver.
+// debug driver. This serves to decouple ProcessWindowsLive from the debug
+// driver.
// It would be possible to get a similar decoupling by just having
-// ProcessWindowsLive implement this interface directly. There are two reasons why
+// ProcessWindowsLive implement this interface directly. There are two reasons
+// why
// we don't do this:
//
// 1) In the future when we add support for local debugging through LLGS, and we
@@ -42,26 +43,26 @@ typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
// driver), so this adapter serves as a way to transparently hold the
// ProcessSP while still keeping it decoupled from the driver.
//----------------------------------------------------------------------
-class LocalDebugDelegate : public IDebugDelegate
-{
- public:
- explicit LocalDebugDelegate(lldb::ProcessWP process);
+class LocalDebugDelegate : public IDebugDelegate {
+public:
+ explicit LocalDebugDelegate(lldb::ProcessWP process);
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override;
- void OnCreateThread(const HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &message) override;
- void OnDebuggerError(const Error &error, uint32_t type) override;
+ void OnExitProcess(uint32_t exit_code) override;
+ void OnDebuggerConnected(lldb::addr_t image_base) override;
+ ExceptionResult OnDebugException(bool first_chance,
+ const ExceptionRecord &record) override;
+ void OnCreateThread(const HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
+ void OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) override;
+ void OnUnloadDll(lldb::addr_t module_addr) override;
+ void OnDebugString(const std::string &message) override;
+ void OnDebuggerError(const Error &error, uint32_t type) override;
- private:
- ProcessWindowsLiveSP
- GetProcessPointer();
+private:
+ ProcessWindowsLiveSP GetProcessPointer();
- lldb::ProcessWP m_process;
+ lldb::ProcessWP m_process;
};
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
index 300e0caa437..9bfa247c2ed 100644
--- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
+++ b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
@@ -24,9 +24,9 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/HostProcess.h"
#include "lldb/Host/HostNativeProcessBase.h"
#include "lldb/Host/HostNativeThreadBase.h"
+#include "lldb/Host/HostProcess.h"
#include "lldb/Host/MonitoringProcessLauncher.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/windows/HostThreadWindows.h"
@@ -56,1014 +56,991 @@ using namespace lldb_private;
#define BOOL_STR(b) ((b) ? "true" : "false")
-namespace
-{
-
-std::string
-GetProcessExecutableName(HANDLE process_handle)
-{
- std::vector<wchar_t> file_name;
- DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
- DWORD copied = 0;
- do
- {
- file_name_size *= 2;
- file_name.resize(file_name_size);
- copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), file_name_size);
- } while (copied >= file_name_size);
- file_name.resize(copied);
- std::string result;
- llvm::convertWideToUTF8(file_name.data(), result);
- return result;
+namespace {
+
+std::string GetProcessExecutableName(HANDLE process_handle) {
+ std::vector<wchar_t> file_name;
+ DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
+ DWORD copied = 0;
+ do {
+ file_name_size *= 2;
+ file_name.resize(file_name_size);
+ copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
+ file_name_size);
+ } while (copied >= file_name_size);
+ file_name.resize(copied);
+ std::string result;
+ llvm::convertWideToUTF8(file_name.data(), result);
+ return result;
}
-std::string
-GetProcessExecutableName(DWORD pid)
-{
- std::string file_name;
- HANDLE process_handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
- if (process_handle != NULL)
- {
- file_name = GetProcessExecutableName(process_handle);
- ::CloseHandle(process_handle);
- }
- return file_name;
+std::string GetProcessExecutableName(DWORD pid) {
+ std::string file_name;
+ HANDLE process_handle =
+ ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ if (process_handle != NULL) {
+ file_name = GetProcessExecutableName(process_handle);
+ ::CloseHandle(process_handle);
+ }
+ return file_name;
}
-} // anonymous namespace
+} // anonymous namespace
-namespace lldb_private
-{
+namespace lldb_private {
-// We store a pointer to this class in the ProcessWindows, so that we don't expose Windows
+// We store a pointer to this class in the ProcessWindows, so that we don't
+// expose Windows
// OS specific types and implementation details from a public header file.
-class ProcessWindowsData
-{
- public:
- ProcessWindowsData(bool stop_at_entry)
- : m_stop_at_entry(stop_at_entry)
- , m_initial_stop_event(nullptr)
- , m_initial_stop_received(false)
- {
- m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- }
-
- ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
-
- lldb_private::Error m_launch_error;
- lldb_private::DebuggerThreadSP m_debugger;
- StopInfoSP m_pending_stop_info;
- HANDLE m_initial_stop_event;
- bool m_stop_at_entry;
- bool m_initial_stop_received;
- std::map<lldb::tid_t, HostThread> m_new_threads;
- std::set<lldb::tid_t> m_exited_threads;
+class ProcessWindowsData {
+public:
+ ProcessWindowsData(bool stop_at_entry)
+ : m_stop_at_entry(stop_at_entry), m_initial_stop_event(nullptr),
+ m_initial_stop_received(false) {
+ m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
+ }
+
+ ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
+
+ lldb_private::Error m_launch_error;
+ lldb_private::DebuggerThreadSP m_debugger;
+ StopInfoSP m_pending_stop_info;
+ HANDLE m_initial_stop_event;
+ bool m_stop_at_entry;
+ bool m_initial_stop_received;
+ std::map<lldb::tid_t, HostThread> m_new_threads;
+ std::set<lldb::tid_t> m_exited_threads;
};
}
//------------------------------------------------------------------------------
// Static functions.
-ProcessSP
-ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *)
-{
- return ProcessSP(new ProcessWindowsLive(target_sp, listener_sp));
+ProcessSP ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const FileSpec *) {
+ return ProcessSP(new ProcessWindowsLive(target_sp, listener_sp));
}
-void
-ProcessWindowsLive::Initialize()
-{
- static std::once_flag g_once_flag;
-
- std::call_once(g_once_flag, []()
- {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
- });
+void ProcessWindowsLive::Initialize() {
+ static std::once_flag g_once_flag;
+
+ std::call_once(g_once_flag, []() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+ });
}
//------------------------------------------------------------------------------
// Constructors and destructors.
-ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
- : lldb_private::ProcessWindows(target_sp, listener_sp)
-{
-}
+ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp)
+ : lldb_private::ProcessWindows(target_sp, listener_sp) {}
-ProcessWindowsLive::~ProcessWindowsLive()
-{
-}
+ProcessWindowsLive::~ProcessWindowsLive() {}
-void
-ProcessWindowsLive::Terminate()
-{
-}
+void ProcessWindowsLive::Terminate() {}
-lldb_private::ConstString
-ProcessWindowsLive::GetPluginNameStatic()
-{
- static ConstString g_name("windows");
- return g_name;
+lldb_private::ConstString ProcessWindowsLive::GetPluginNameStatic() {
+ static ConstString g_name("windows");
+ return g_name;
}
-const char *
-ProcessWindowsLive::GetPluginDescriptionStatic()
-{
- return "Process plugin for Windows";
+const char *ProcessWindowsLive::GetPluginDescriptionStatic() {
+ return "Process plugin for Windows";
}
-Error
-ProcessWindowsLive::EnableBreakpointSite(BreakpointSite *bp_site)
-{
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite called with bp_site 0x%p "
- "(id=%d, addr=0x%x)",
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Error error = EnableSoftwareBreakpoint(bp_site);
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s", error.AsCString());
- }
- return error;
+Error ProcessWindowsLive::EnableBreakpointSite(BreakpointSite *bp_site) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS,
+ "EnableBreakpointSite called with bp_site 0x%p "
+ "(id=%d, addr=0x%x)",
+ bp_site->GetID(), bp_site->GetLoadAddress());
+
+ Error error = EnableSoftwareBreakpoint(bp_site);
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s",
+ error.AsCString());
+ }
+ return error;
}
-Error
-ProcessWindowsLive::DisableBreakpointSite(BreakpointSite *bp_site)
-{
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite called with bp_site 0x%p "
- "(id=%d, addr=0x%x)",
- bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
+Error ProcessWindowsLive::DisableBreakpointSite(BreakpointSite *bp_site) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS,
+ "DisableBreakpointSite called with bp_site 0x%p "
+ "(id=%d, addr=0x%x)",
+ bp_site, bp_site->GetID(), bp_site->GetLoadAddress());
- Error error = DisableSoftwareBreakpoint(bp_site);
+ Error error = DisableSoftwareBreakpoint(bp_site);
- if (!error.Success())
- {
- WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s", error.AsCString());
- }
- return error;
+ if (!error.Success()) {
+ WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s",
+ error.AsCString());
+ }
+ return error;
}
-bool
-ProcessWindowsLive::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- // Add all the threads that were previously running and for which we did not detect a thread
- // exited event.
- int new_size = 0;
- int continued_threads = 0;
- int exited_threads = 0;
- int new_threads = 0;
-
- for (ThreadSP old_thread : old_thread_list.Threads())
- {
- lldb::tid_t old_thread_id = old_thread->GetID();
- auto exited_thread_iter = m_session_data->m_exited_threads.find(old_thread_id);
- if (exited_thread_iter == m_session_data->m_exited_threads.end())
- {
- new_thread_list.AddThread(old_thread);
- ++new_size;
- ++continued_threads;
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u was running and is still running.",
- old_thread_id);
- }
- else
- {
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u was running and has exited.",
- old_thread_id);
- ++exited_threads;
- }
- }
-
- // Also add all the threads that are new since the last time we broke into the debugger.
- for (const auto &thread_info : m_session_data->m_new_threads)
- {
- ThreadSP thread(new TargetThreadWindowsLive(*this, thread_info.second));
- thread->SetID(thread_info.first);
- new_thread_list.AddThread(thread);
- ++new_size;
- ++new_threads;
- WINLOGV_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - Thread %u is new since last update.", thread_info.first);
+bool ProcessWindowsLive::UpdateThreadList(ThreadList &old_thread_list,
+ ThreadList &new_thread_list) {
+ // Add all the threads that were previously running and for which we did not
+ // detect a thread
+ // exited event.
+ int new_size = 0;
+ int continued_threads = 0;
+ int exited_threads = 0;
+ int new_threads = 0;
+
+ for (ThreadSP old_thread : old_thread_list.Threads()) {
+ lldb::tid_t old_thread_id = old_thread->GetID();
+ auto exited_thread_iter =
+ m_session_data->m_exited_threads.find(old_thread_id);
+ if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
+ new_thread_list.AddThread(old_thread);
+ ++new_size;
+ ++continued_threads;
+ WINLOGV_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %u was running and is still running.",
+ old_thread_id);
+ } else {
+ WINLOGV_IFALL(WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %u was running and has exited.",
+ old_thread_id);
+ ++exited_threads;
}
-
- WINLOG_IFALL(WINDOWS_LOG_THREAD, "UpdateThreadList - %d new threads, %d old threads, %d exited threads.",
- new_threads, continued_threads, exited_threads);
-
- m_session_data->m_new_threads.clear();
- m_session_data->m_exited_threads.clear();
-
- return new_size > 0;
+ }
+
+ // Also add all the threads that are new since the last time we broke into the
+ // debugger.
+ for (const auto &thread_info : m_session_data->m_new_threads) {
+ ThreadSP thread(new TargetThreadWindowsLive(*this, thread_info.second));
+ thread->SetID(thread_info.first);
+ new_thread_list.AddThread(thread);
+ ++new_size;
+ ++new_threads;
+ WINLOGV_IFALL(WINDOWS_LOG_THREAD,
+ "UpdateThreadList - Thread %u is new since last update.",
+ thread_info.first);
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_THREAD,
+ "UpdateThreadList - %d new threads, %d old threads, %d exited threads.",
+ new_threads, continued_threads, exited_threads);
+
+ m_session_data->m_new_threads.clear();
+ m_session_data->m_exited_threads.clear();
+
+ return new_size > 0;
}
-Error
-ProcessWindowsLive::DoLaunch(Module *exe_module,
- ProcessLaunchInfo &launch_info)
-{
- // Even though m_session_data is accessed here, it is before a debugger thread has been
- // kicked off. So there's no race conditions, and it shouldn't be necessary to acquire
- // the mutex.
-
- Error result;
- if (!launch_info.GetFlags().Test(eLaunchFlagDebug))
- {
- StreamString stream;
- stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can only be used for debug launches.",
- launch_info.GetExecutableFile().GetPath().c_str());
- std::string message = stream.GetString();
- result.SetErrorString(message.c_str());
-
- WINERR_IFALL(WINDOWS_LOG_PROCESS, message.c_str());
- return result;
- }
-
- bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
- m_session_data.reset(new ProcessWindowsData(stop_at_entry));
-
- SetPrivateState(eStateLaunching);
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- m_session_data->m_debugger.reset(new DebuggerThread(delegate));
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- // Kick off the DebugLaunch asynchronously and wait for it to complete.
- result = debugger->DebugLaunch(launch_info);
- if (result.Fail())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
- launch_info.GetExecutableFile().GetPath().c_str(), result.AsCString());
- return result;
- }
-
- HostProcess process;
- Error error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail())
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
- launch_info.GetExecutableFile().GetPath().c_str(), error.AsCString());
- return error;
- }
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
- launch_info.GetExecutableFile().GetPath().c_str());
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the private state
- // should already be set to eStateStopped as a result of hitting the initial breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and the private state
- // should already be eStateRunning.
- launch_info.SetProcessID(process.GetProcessId());
- SetID(process.GetProcessId());
-
+Error ProcessWindowsLive::DoLaunch(Module *exe_module,
+ ProcessLaunchInfo &launch_info) {
+ // Even though m_session_data is accessed here, it is before a debugger thread
+ // has been
+ // kicked off. So there's no race conditions, and it shouldn't be necessary
+ // to acquire
+ // the mutex.
+
+ Error result;
+ if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
+ StreamString stream;
+ stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can "
+ "only be used for debug launches.",
+ launch_info.GetExecutableFile().GetPath().c_str());
+ std::string message = stream.GetString();
+ result.SetErrorString(message.c_str());
+
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, message.c_str());
return result;
+ }
+
+ bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
+ m_session_data.reset(new ProcessWindowsData(stop_at_entry));
+
+ SetPrivateState(eStateLaunching);
+ DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
+ m_session_data->m_debugger.reset(new DebuggerThread(delegate));
+ DebuggerThreadSP debugger = m_session_data->m_debugger;
+
+ // Kick off the DebugLaunch asynchronously and wait for it to complete.
+ result = debugger->DebugLaunch(launch_info);
+ if (result.Fail()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
+ launch_info.GetExecutableFile().GetPath().c_str(),
+ result.AsCString());
+ return result;
+ }
+
+ HostProcess process;
+ Error error = WaitForDebuggerConnection(debugger, process);
+ if (error.Fail()) {
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s",
+ launch_info.GetExecutableFile().GetPath().c_str(),
+ error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'",
+ launch_info.GetExecutableFile().GetPath().c_str());
+
+ // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
+ // private state
+ // should already be set to eStateStopped as a result of hitting the initial
+ // breakpoint. If
+ // it was not set, the breakpoint should have already been resumed from and
+ // the private state
+ // should already be eStateRunning.
+ launch_info.SetProcessID(process.GetProcessId());
+ SetID(process.GetProcessId());
+
+ return result;
}
-Error
-ProcessWindowsLive::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
-{
- m_session_data.reset(new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
-
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- DebuggerThreadSP debugger(new DebuggerThread(delegate));
-
- m_session_data->m_debugger = debugger;
+Error ProcessWindowsLive::DoAttachToProcessWithID(
+ lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
+ m_session_data.reset(
+ new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
- DWORD process_id = static_cast<DWORD>(pid);
- Error error = debugger->DebugAttach(process_id, attach_info);
- if (error.Fail())
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DoAttachToProcessWithID encountered an error occurred initiating the asynchronous attach. %s",
- error.AsCString());
- return error;
- }
-
- HostProcess process;
- error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail())
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS,
- "DoAttachToProcessWithID encountered an error waiting for the debugger to connect. %s",
- error.AsCString());
- return error;
- }
+ DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
+ DebuggerThreadSP debugger(new DebuggerThread(delegate));
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID successfully attached to process with pid=%u",
- process_id);
+ m_session_data->m_debugger = debugger;
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the private state
- // should already be set to eStateStopped as a result of hitting the initial breakpoint. If
- // it was not set, the breakpoint should have already been resumed from and the private state
- // should already be eStateRunning.
- SetID(process.GetProcessId());
+ DWORD process_id = static_cast<DWORD>(pid);
+ Error error = debugger->DebugAttach(process_id, attach_info);
+ if (error.Fail()) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an "
+ "error occurred initiating the "
+ "asynchronous attach. %s",
+ error.AsCString());
+ return error;
+ }
+
+ HostProcess process;
+ error = WaitForDebuggerConnection(debugger, process);
+ if (error.Fail()) {
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an "
+ "error waiting for the debugger to "
+ "connect. %s",
+ error.AsCString());
return error;
+ }
+
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoAttachToProcessWithID successfully attached to process with pid=%u",
+ process_id);
+
+ // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
+ // private state
+ // should already be set to eStateStopped as a result of hitting the initial
+ // breakpoint. If
+ // it was not set, the breakpoint should have already been resumed from and
+ // the private state
+ // should already be eStateRunning.
+ SetID(process.GetProcessId());
+ return error;
}
-Error
-ProcessWindowsLive::WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess &process)
-{
- Error result;
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection Waiting for loader breakpoint.");
-
- // Block this function until we receive the initial stop from the process.
- if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) == WAIT_OBJECT_0)
- {
- WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection hit loader breakpoint, returning.");
+Error ProcessWindowsLive::WaitForDebuggerConnection(DebuggerThreadSP debugger,
+ HostProcess &process) {
+ Error result;
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS,
+ "WaitForDebuggerConnection Waiting for loader breakpoint.");
+
+ // Block this function until we receive the initial stop from the process.
+ if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
+ WAIT_OBJECT_0) {
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS,
+ "WaitForDebuggerConnection hit loader breakpoint, returning.");
+
+ process = debugger->GetProcess();
+ return m_session_data->m_launch_error;
+ } else
+ return Error(::GetLastError(), eErrorTypeWin32);
+}
- process = debugger->GetProcess();
- return m_session_data->m_launch_error;
+Error ProcessWindowsLive::DoResume() {
+ llvm::sys::ScopedLock lock(m_mutex);
+ Error error;
+
+ StateType private_state = GetPrivateState();
+ if (private_state == eStateStopped || private_state == eStateCrashed) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoResume called for process %I64u while state is %u. Resuming...",
+ m_session_data->m_debugger->GetProcess().GetProcessId(),
+ GetPrivateState());
+
+ ExceptionRecordSP active_exception =
+ m_session_data->m_debugger->GetActiveException().lock();
+ if (active_exception) {
+ // Resume the process and continue processing debug events. Mask
+ // the exception so that from the process's view, there is no
+ // indication that anything happened.
+ m_session_data->m_debugger->ContinueAsyncException(
+ ExceptionResult::MaskException);
}
- else
- return Error(::GetLastError(), eErrorTypeWin32);
-}
-Error
-ProcessWindowsLive::DoResume()
-{
- llvm::sys::ScopedLock lock(m_mutex);
- Error error;
+ WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD,
+ "DoResume resuming %u threads.", m_thread_list.GetSize());
- StateType private_state = GetPrivateState();
- if (private_state == eStateStopped || private_state == eStateCrashed)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoResume called for process %I64u while state is %u. Resuming...",
- m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState());
-
- ExceptionRecordSP active_exception =
- m_session_data->m_debugger->GetActiveException().lock();
- if (active_exception)
- {
- // Resume the process and continue processing debug events. Mask
- // the exception so that from the process's view, there is no
- // indication that anything happened.
- m_session_data->m_debugger->ContinueAsyncException(
- ExceptionResult::MaskException);
- }
-
- WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD, "DoResume resuming %u threads.",
- m_thread_list.GetSize());
-
- for (int i = 0; i < m_thread_list.GetSize(); ++i)
- {
- auto thread = std::static_pointer_cast<TargetThreadWindowsLive>(
- m_thread_list.GetThreadAtIndex(i));
- thread->DoResume();
- }
-
- SetPrivateState(eStateRunning);
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoResume called for process %I64u but state is %u. Returning...",
- m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState());
+ for (int i = 0; i < m_thread_list.GetSize(); ++i) {
+ auto thread = std::static_pointer_cast<TargetThreadWindowsLive>(
+ m_thread_list.GetThreadAtIndex(i));
+ thread->DoResume();
}
- return error;
-}
+ SetPrivateState(eStateRunning);
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoResume called for process %I64u but state is %u. Returning...",
+ m_session_data->m_debugger->GetProcess().GetProcessId(),
+ GetPrivateState());
+ }
+ return error;
+}
//------------------------------------------------------------------------------
// ProcessInterface protocol.
-lldb_private::ConstString
-ProcessWindowsLive::GetPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-ProcessWindowsLive::GetPluginVersion()
-{
- return 1;
+lldb_private::ConstString ProcessWindowsLive::GetPluginName() {
+ return GetPluginNameStatic();
}
-Error
-ProcessWindowsLive::DoDetach(bool keep_stopped)
-{
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire the lock only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which
- // will also acquire the lock. Thus we have to release the lock before
- // calling StopDebugging().
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "DoDetach called while state = %u, but there is no active session.",
- private_state);
- return Error();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
+uint32_t ProcessWindowsLive::GetPluginVersion() { return 1; }
- Error error;
- if (private_state != eStateExited && private_state != eStateDetached)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoDetach called for process %I64u while state = %u. Detaching...",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- error = debugger_thread->StopDebugging(false);
- if (error.Success())
- {
- SetPrivateState(eStateDetached);
- }
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DoDetach called for process %I64u while state = %u, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- }
+Error ProcessWindowsLive::DoDetach(bool keep_stopped) {
+ DebuggerThreadSP debugger_thread;
+ StateType private_state;
+ {
+ // Acquire the lock only long enough to get the DebuggerThread.
+ // StopDebugging() will trigger a call back into ProcessWindows which
+ // will also acquire the lock. Thus we have to release the lock before
+ // calling StopDebugging().
+ llvm::sys::ScopedLock lock(m_mutex);
- return error;
-}
+ private_state = GetPrivateState();
-Error
-ProcessWindowsLive::DoDestroy()
-{
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire this lock inside an inner scope, only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which will acquire the lock
- // again, so we need to not deadlock.
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "DoDestroy called while state = %u, but there is no active session.",
- private_state);
- return Error();
- }
-
- debugger_thread = m_session_data->m_debugger;
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDetach called while state = %u, but there is no active session.",
+ private_state);
+ return Error();
}
- Error error;
- if (private_state != eStateExited && private_state != eStateDetached)
- {
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoDestroy called for process %I64u while state = %u. Shutting down...",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
- error = debugger_thread->StopDebugging(true);
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- }
- else
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS,
- "DoDestroy called for process %I64u while state = %u, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), private_state);
+ debugger_thread = m_session_data->m_debugger;
+ }
+
+ Error error;
+ if (private_state != eStateExited && private_state != eStateDetached) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDetach called for process %I64u while state = %u. Detaching...",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ error = debugger_thread->StopDebugging(false);
+ if (error.Success()) {
+ SetPrivateState(eStateDetached);
}
- return error;
+ // By the time StopDebugging returns, there is no more debugger thread, so
+ // we can be assured that no other thread will race for the session data.
+ m_session_data.reset();
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDetach called for process %I64u while state = "
+ "%u, but cannot destroy in this state.",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ }
+
+ return error;
}
-void
-ProcessWindowsLive::RefreshStateAfterStop()
-{
+Error ProcessWindowsLive::DoDestroy() {
+ DebuggerThreadSP debugger_thread;
+ StateType private_state;
+ {
+ // Acquire this lock inside an inner scope, only long enough to get the
+ // DebuggerThread.
+ // StopDebugging() will trigger a call back into ProcessWindows which will
+ // acquire the lock
+ // again, so we need to not deadlock.
llvm::sys::ScopedLock lock(m_mutex);
- if (!m_session_data)
- {
- WINWARN_IFALL(WINDOWS_LOG_PROCESS, "RefreshStateAfterStop called with no active session. Returning...");
- return;
- }
-
- m_thread_list.RefreshStateAfterStop();
+ private_state = GetPrivateState();
- std::weak_ptr<ExceptionRecord> exception_record = m_session_data->m_debugger->GetActiveException();
- ExceptionRecordSP active_exception = exception_record.lock();
- if (!active_exception)
- {
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "RefreshStateAfterStop called for process %I64u but there is no "
- "active exception. Why is the process stopped?",
- m_session_data->m_debugger->GetProcess().GetProcessId());
- return;
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoDestroy called while state = %u, but there is no active session.",
+ private_state);
+ return Error();
}
- StopInfoSP stop_info;
- m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- ThreadSP stop_thread = m_thread_list.GetSelectedThread();
- if (!stop_thread)
- return;
-
- switch (active_exception->GetExceptionCode())
- {
- case EXCEPTION_SINGLE_STEP:
- {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
- const uint64_t pc = register_context->GetPC();
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site && site->ValidForThisThread(stop_thread.get()))
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
- "Single-stepped onto a breakpoint in process %I64u at "
- "address 0x%I64x with breakpoint site %d",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, site->GetID());
- stop_thread->SetStopInfo(stop_info);
- }
- else
- {
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
- "RefreshStateAfterStop single stepping thread %u", stop_thread->GetID());
- stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
- stop_thread->SetStopInfo(stop_info);
- }
- return;
- }
-
- case EXCEPTION_BREAKPOINT:
- {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
-
- // The current EIP is AFTER the BP opcode, which is one byte.
- uint64_t pc = register_context->GetPC() - 1;
-
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site)
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "RefreshStateAfterStop detected breakpoint in process %I64u at "
- "address 0x%I64x with breakpoint site %d",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID());
-
- if (site->ValidForThisThread(stop_thread.get()))
- {
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is valid for this thread (0x%I64x), creating stop info.",
- site->GetID(), stop_thread->GetID());
-
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
- *stop_thread, site->GetID());
- register_context->SetPC(pc);
- }
- else
- {
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "Breakpoint site %d is not valid for this thread, creating empty stop info.",
- site->GetID());
- }
- stop_thread->SetStopInfo(stop_info);
- return;
- }
- else
- {
- // The thread hit a hard-coded breakpoint like an `int 3` or `__debugbreak()`.
- WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
- "No breakpoint site matches for this thread. __debugbreak()? "
- "Creating stop info with the exception.");
- // FALLTHROUGH: We'll treat this as a generic exception record in the default case.
- }
- }
-
- default:
- {
- std::string desc;
- llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception " << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address "
- << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- stop_info = StopInfo::CreateStopReasonWithException(*stop_thread, desc_stream.str().c_str());
- stop_thread->SetStopInfo(stop_info);
- WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, desc_stream.str().c_str());
- return;
- }
- }
+ debugger_thread = m_session_data->m_debugger;
+ }
+
+ Error error;
+ if (private_state != eStateExited && private_state != eStateDetached) {
+ WINLOG_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDestroy called for process %I64u while state = "
+ "%u. Shutting down...",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ error = debugger_thread->StopDebugging(true);
+
+ // By the time StopDebugging returns, there is no more debugger thread, so
+ // we can be assured that no other thread will race for the session data.
+ m_session_data.reset();
+ } else {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS, "DoDestroy called for process %I64u while state = "
+ "%u, but cannot destroy in this state.",
+ debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
+ private_state);
+ }
+
+ return error;
}
-bool
-ProcessWindowsLive::IsAlive()
-{
- StateType state = GetPrivateState();
- switch (state)
- {
- case eStateCrashed:
- case eStateDetached:
- case eStateUnloaded:
- case eStateExited:
- case eStateInvalid:
- return false;
- default:
- return true;
+void ProcessWindowsLive::RefreshStateAfterStop() {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (!m_session_data) {
+ WINWARN_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "RefreshStateAfterStop called with no active session. Returning...");
+ return;
+ }
+
+ m_thread_list.RefreshStateAfterStop();
+
+ std::weak_ptr<ExceptionRecord> exception_record =
+ m_session_data->m_debugger->GetActiveException();
+ ExceptionRecordSP active_exception = exception_record.lock();
+ if (!active_exception) {
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "RefreshStateAfterStop called for process %I64u but there is no "
+ "active exception. Why is the process stopped?",
+ m_session_data->m_debugger->GetProcess().GetProcessId());
+ return;
+ }
+
+ StopInfoSP stop_info;
+ m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
+ ThreadSP stop_thread = m_thread_list.GetSelectedThread();
+ if (!stop_thread)
+ return;
+
+ switch (active_exception->GetExceptionCode()) {
+ case EXCEPTION_SINGLE_STEP: {
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+ const uint64_t pc = register_context->GetPC();
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site && site->ValidForThisThread(stop_thread.get())) {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION |
+ WINDOWS_LOG_STEP,
+ "Single-stepped onto a breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
+ site->GetID());
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
+ site->GetID());
+ stop_thread->SetStopInfo(stop_info);
+ } else {
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP,
+ "RefreshStateAfterStop single stepping thread %u",
+ stop_thread->GetID());
+ stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
+ stop_thread->SetStopInfo(stop_info);
}
-}
-
-Error
-ProcessWindowsLive::DoHalt(bool &caused_stop)
-{
- Error error;
- StateType state = GetPrivateState();
- if (state == eStateStopped)
- caused_stop = false;
- else
- {
- llvm::sys::ScopedLock lock(m_mutex);
- caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess().GetNativeProcess().GetSystemHandle());
- if (!caused_stop)
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoHalt called DebugBreakProcess, but it failed with error %u",
- error.GetError());
- }
+ return;
+ }
+
+ case EXCEPTION_BREAKPOINT: {
+ RegisterContextSP register_context = stop_thread->GetRegisterContext();
+
+ // The current EIP is AFTER the BP opcode, which is one byte.
+ uint64_t pc = register_context->GetPC() - 1;
+
+ BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+ if (site) {
+ WINLOG_IFANY(
+ WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "RefreshStateAfterStop detected breakpoint in process %I64u at "
+ "address 0x%I64x with breakpoint site %d",
+ m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
+ site->GetID());
+
+ if (site->ValidForThisThread(stop_thread.get())) {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "Breakpoint site %d is valid for this thread (0x%I64x), "
+ "creating stop info.",
+ site->GetID(), stop_thread->GetID());
+
+ stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
+ *stop_thread, site->GetID());
+ register_context->SetPC(pc);
+ } else {
+ WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "Breakpoint site %d is not valid for this thread, "
+ "creating empty stop info.",
+ site->GetID());
+ }
+ stop_thread->SetStopInfo(stop_info);
+ return;
+ } else {
+ // The thread hit a hard-coded breakpoint like an `int 3` or
+ // `__debugbreak()`.
+ WINLOG_IFALL(
+ WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION,
+ "No breakpoint site matches for this thread. __debugbreak()? "
+ "Creating stop info with the exception.");
+ // FALLTHROUGH: We'll treat this as a generic exception record in the
+ // default case.
}
- return error;
-}
-
-void
-ProcessWindowsLive::DidLaunch()
-{
- ArchSpec arch_spec;
- DidAttach(arch_spec);
+ }
+
+ default: {
+ std::string desc;
+ llvm::raw_string_ostream desc_stream(desc);
+ desc_stream << "Exception "
+ << llvm::format_hex(active_exception->GetExceptionCode(), 8)
+ << " encountered at address "
+ << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
+ stop_info = StopInfo::CreateStopReasonWithException(
+ *stop_thread, desc_stream.str().c_str());
+ stop_thread->SetStopInfo(stop_info);
+ WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, desc_stream.str().c_str());
+ return;
+ }
+ }
}
-void
-ProcessWindowsLive::DidAttach(ArchSpec &arch_spec)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // The initial stop won't broadcast the state change event, so account for that here.
- if (m_session_data && GetPrivateState() == eStateStopped && m_session_data->m_stop_at_entry)
- RefreshStateAfterStop();
+bool ProcessWindowsLive::IsAlive() {
+ StateType state = GetPrivateState();
+ switch (state) {
+ case eStateCrashed:
+ case eStateDetached:
+ case eStateUnloaded:
+ case eStateExited:
+ case eStateInvalid:
+ return false;
+ default:
+ return true;
+ }
}
-size_t
-ProcessWindowsLive::DoReadMemory(lldb::addr_t vm_addr,
- void *buf,
- size_t size,
- Error &error)
-{
+Error ProcessWindowsLive::DoHalt(bool &caused_stop) {
+ Error error;
+ StateType state = GetPrivateState();
+ if (state == eStateStopped)
+ caused_stop = false;
+ else {
llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- return 0;
-
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory attempting to read %u bytes from address 0x%I64x", size, vm_addr);
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_read = 0;
- if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr, buf, size, &bytes_read))
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u", error.GetError());
+ caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
+ .GetNativeProcess()
+ .GetSystemHandle());
+ if (!caused_stop) {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "DoHalt called DebugBreakProcess, but it failed with error %u",
+ error.GetError());
}
- return bytes_read;
+ }
+ return error;
}
-size_t
-ProcessWindowsLive::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error)
-{
- llvm::sys::ScopedLock lock(m_mutex);
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size, vm_addr);
+void ProcessWindowsLive::DidLaunch() {
+ ArchSpec arch_spec;
+ DidAttach(arch_spec);
+}
- if (!m_session_data)
- {
- WINERR_IFANY(WINDOWS_LOG_MEMORY, "DoWriteMemory cannot write, there is no active debugger connection.");
- return 0;
- }
+void ProcessWindowsLive::DidAttach(ArchSpec &arch_spec) {
+ llvm::sys::ScopedLock lock(m_mutex);
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_written = 0;
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
- FlushInstructionCache(handle, addr, bytes_written);
- else
- {
- error.SetError(GetLastError(), eErrorTypeWin32);
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u", error.GetError());
- }
- return bytes_written;
+ // The initial stop won't broadcast the state change event, so account for
+ // that here.
+ if (m_session_data && GetPrivateState() == eStateStopped &&
+ m_session_data->m_stop_at_entry)
+ RefreshStateAfterStop();
}
-Error
-ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info)
-{
- Error error;
- llvm::sys::ScopedLock lock(m_mutex);
- info.Clear();
+size_t ProcessWindowsLive::DoReadMemory(lldb::addr_t vm_addr, void *buf,
+ size_t size, Error &error) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (!m_session_data)
+ return 0;
+
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY,
+ "DoReadMemory attempting to read %u bytes from address 0x%I64x",
+ size, vm_addr);
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ SIZE_T bytes_read = 0;
+ if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
+ buf, size, &bytes_read)) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u",
+ error.GetError());
+ }
+ return bytes_read;
+}
- if (!m_session_data)
- {
- error.SetErrorString("GetMemoryRegionInfo called with no debugging session.");
- WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
- return error;
- }
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
- {
- error.SetErrorString("GetMemoryRegionInfo called with an invalid target process.");
- WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
- return error;
- }
+size_t ProcessWindowsLive::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
+ size_t size, Error &error) {
+ llvm::sys::ScopedLock lock(m_mutex);
+ WINLOG_IFALL(
+ WINDOWS_LOG_MEMORY,
+ "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size,
+ vm_addr);
+
+ if (!m_session_data) {
+ WINERR_IFANY(
+ WINDOWS_LOG_MEMORY,
+ "DoWriteMemory cannot write, there is no active debugger connection.");
+ return 0;
+ }
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ SIZE_T bytes_written = 0;
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
+ FlushInstructionCache(handle, addr, bytes_written);
+ else {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u",
+ error.GetError());
+ }
+ return bytes_written;
+}
- WINLOG_IFALL(WINDOWS_LOG_MEMORY, "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);
-
- void *addr = reinterpret_cast<void *>(vm_addr);
- MEMORY_BASIC_INFORMATION mem_info = {0};
- SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
- if (result == 0)
- {
- if (::GetLastError() == ERROR_INVALID_PARAMETER)
- {
- // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an address
- // past the highest accessible address. We should return a range from the vm_addr
- // to LLDB_INVALID_ADDRESS
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- info.SetMapped(MemoryRegionInfo::eNo);
- return error;
- }
- else
- {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINERR_IFALL(WINDOWS_LOG_MEMORY,
- "VirtualQueryEx returned error %u while getting memory region info for address 0x%I64x",
- error.GetError(), vm_addr);
- return error;
- }
- }
+Error ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) {
+ Error error;
+ llvm::sys::ScopedLock lock(m_mutex);
+ info.Clear();
- // Protect bits are only valid for MEM_COMMIT regions.
- if (mem_info.State == MEM_COMMIT) {
- const bool readable = IsPageReadable(mem_info.Protect);
- const bool executable = IsPageExecutable(mem_info.Protect);
- const bool writable = IsPageWritable(mem_info.Protect);
- info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(executable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- }
- else
- {
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
+ if (!m_session_data) {
+ error.SetErrorString(
+ "GetMemoryRegionInfo called with no debugging session.");
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
+ return error;
+ }
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
+ error.SetErrorString(
+ "GetMemoryRegionInfo called with an invalid target process.");
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, error.AsCString());
+ return error;
+ }
+
+ WINLOG_IFALL(WINDOWS_LOG_MEMORY,
+ "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr);
+
+ void *addr = reinterpret_cast<void *>(vm_addr);
+ MEMORY_BASIC_INFORMATION mem_info = {0};
+ SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
+ if (result == 0) {
+ if (::GetLastError() == ERROR_INVALID_PARAMETER) {
+ // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an
+ // address
+ // past the highest accessible address. We should return a range from the
+ // vm_addr
+ // to LLDB_INVALID_ADDRESS
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ return error;
+ } else {
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINERR_IFALL(WINDOWS_LOG_MEMORY, "VirtualQueryEx returned error %u while "
+ "getting memory region info for address "
+ "0x%I64x",
+ error.GetError(), vm_addr);
+ return error;
}
+ }
+
+ // Protect bits are only valid for MEM_COMMIT regions.
+ if (mem_info.State == MEM_COMMIT) {
+ const bool readable = IsPageReadable(mem_info.Protect);
+ const bool executable = IsPageExecutable(mem_info.Protect);
+ const bool writable = IsPageWritable(mem_info.Protect);
+ info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ info.SetExecutable(executable ? MemoryRegionInfo::eYes
+ : MemoryRegionInfo::eNo);
+ info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
+ } else {
+ info.SetReadable(MemoryRegionInfo::eNo);
+ info.SetExecutable(MemoryRegionInfo::eNo);
+ info.SetWritable(MemoryRegionInfo::eNo);
+ }
+
+ // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
+ if (mem_info.State != MEM_FREE) {
+ info.GetRange().SetRangeBase(
+ reinterpret_cast<addr_t>(mem_info.AllocationBase));
+ info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
+ mem_info.RegionSize);
+ info.SetMapped(MemoryRegionInfo::eYes);
+ } else {
+ // In the unmapped case we need to return the distance to the next block of
+ // memory.
+ // VirtualQueryEx nearly does that except that it gives the distance from
+ // the start
+ // of the page containing vm_addr.
+ SYSTEM_INFO data;
+ GetSystemInfo(&data);
+ DWORD page_offset = vm_addr % data.dwPageSize;
+ info.GetRange().SetRangeBase(vm_addr);
+ info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
+ info.SetMapped(MemoryRegionInfo::eNo);
+ }
+
+ error.SetError(::GetLastError(), eErrorTypeWin32);
+ WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: "
+ "readable=%s, executable=%s, writable=%s",
+ BOOL_STR(info.GetReadable()), BOOL_STR(info.GetExecutable()),
+ BOOL_STR(info.GetWritable()));
+ return error;
+}
- // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
- if (mem_info.State != MEM_FREE) {
- info.GetRange().SetRangeBase(reinterpret_cast<addr_t>(mem_info.AllocationBase));
- info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) + mem_info.RegionSize);
- info.SetMapped(MemoryRegionInfo::eYes);
- }
- else
- {
- // In the unmapped case we need to return the distance to the next block of memory.
- // VirtualQueryEx nearly does that except that it gives the distance from the start
- // of the page containing vm_addr.
- SYSTEM_INFO data;
- GetSystemInfo(&data);
- DWORD page_offset = vm_addr % data.dwPageSize;
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
- info.SetMapped(MemoryRegionInfo::eNo);
- }
+bool ProcessWindowsLive::CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) {
+ if (plugin_specified_by_name)
+ return true;
- error.SetError(::GetLastError(), eErrorTypeWin32);
- WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address 0x%I64u: readable=%s, executable=%s, writable=%s",
- BOOL_STR(info.GetReadable()), BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable()));
- return error;
+ // For now we are just making sure the file exists for a given module
+ ModuleSP exe_module_sp(target_sp->GetExecutableModule());
+ if (exe_module_sp.get())
+ return exe_module_sp->GetFileSpec().Exists();
+ // However, if there is no executable module, we return true since we might be
+ // preparing to attach.
+ return true;
}
-bool
-ProcessWindowsLive::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- ModuleSP exe_module_sp(target_sp->GetExecutableModule());
- if (exe_module_sp.get())
- return exe_module_sp->GetFileSpec().Exists();
- // However, if there is no executable module, we return true since we might be preparing to attach.
- return true;
+void ProcessWindowsLive::OnExitProcess(uint32_t exit_code) {
+ // No need to acquire the lock since m_session_data isn't accessed.
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %u exited with code %u", GetID(),
+ exit_code);
+
+ TargetSP target = m_target_sp.lock();
+ if (target) {
+ ModuleSP executable_module = target->GetExecutableModule();
+ ModuleList unloaded_modules;
+ unloaded_modules.Append(executable_module);
+ target->ModulesDidUnload(unloaded_modules, true);
+ }
+
+ SetProcessExitStatus(GetID(), true, 0, exit_code);
+ SetPrivateState(eStateExited);
}
-void
-ProcessWindowsLive::OnExitProcess(uint32_t exit_code)
-{
- // No need to acquire the lock since m_session_data isn't accessed.
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %u exited with code %u", GetID(), exit_code);
-
- TargetSP target = m_target_sp.lock();
- if (target)
- {
- ModuleSP executable_module = target->GetExecutableModule();
- ModuleList unloaded_modules;
- unloaded_modules.Append(executable_module);
- target->ModulesDidUnload(unloaded_modules, true);
- }
+void ProcessWindowsLive::OnDebuggerConnected(lldb::addr_t image_base) {
+ DebuggerThreadSP debugger = m_session_data->m_debugger;
- SetProcessExitStatus(GetID(), true, 0, exit_code);
- SetPrivateState(eStateExited);
-}
+ WINLOG_IFALL(WINDOWS_LOG_PROCESS,
+ "Debugger connected to process %I64u. Image base = 0x%I64x",
+ debugger->GetProcess().GetProcessId(), image_base);
-void
-ProcessWindowsLive::OnDebuggerConnected(lldb::addr_t image_base)
-{
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Debugger connected to process %I64u. Image base = 0x%I64x",
- debugger->GetProcess().GetProcessId(), image_base);
-
- ModuleSP module = GetTarget().GetExecutableModule();
- if (!module)
- {
- // During attach, we won't have the executable module, so find it now.
- const DWORD pid = debugger->GetProcess().GetProcessId();
- const std::string file_name = GetProcessExecutableName(pid);
- if (file_name.empty())
- {
- return;
- }
-
- FileSpec executable_file(file_name, true);
- ModuleSpec module_spec(executable_file);
- Error error;
- module = GetTarget().GetSharedModule(module_spec, &error);
- if (!module)
- {
- return;
- }
-
- GetTarget().SetExecutableModule(module, false);
+ ModuleSP module = GetTarget().GetExecutableModule();
+ if (!module) {
+ // During attach, we won't have the executable module, so find it now.
+ const DWORD pid = debugger->GetProcess().GetProcessId();
+ const std::string file_name = GetProcessExecutableName(pid);
+ if (file_name.empty()) {
+ return;
}
- bool load_addr_changed;
- module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
+ FileSpec executable_file(file_name, true);
+ ModuleSpec module_spec(executable_file);
+ Error error;
+ module = GetTarget().GetSharedModule(module_spec, &error);
+ if (!module) {
+ return;
+ }
- // Add the main executable module to the list of pending module loads. We can't call
- // GetTarget().ModulesDidLoad() here because we still haven't returned from DoLaunch() / DoAttach() yet
- // so the target may not have set the process instance to `this` yet.
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wmain_thread = debugger->GetMainThread().GetNativeThread();
- m_session_data->m_new_threads[wmain_thread.GetThreadId()] = debugger->GetMainThread();
+ GetTarget().SetExecutableModule(module, false);
+ }
+
+ bool load_addr_changed;
+ module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
+
+ ModuleList loaded_modules;
+ loaded_modules.Append(module);
+ GetTarget().ModulesDidLoad(loaded_modules);
+
+ // Add the main executable module to the list of pending module loads. We
+ // can't call
+ // GetTarget().ModulesDidLoad() here because we still haven't returned from
+ // DoLaunch() / DoAttach() yet
+ // so the target may not have set the process instance to `this` yet.
+ llvm::sys::ScopedLock lock(m_mutex);
+ const HostThreadWindows &wmain_thread =
+ debugger->GetMainThread().GetNativeThread();
+ m_session_data->m_new_threads[wmain_thread.GetThreadId()] =
+ debugger->GetMainThread();
}
ExceptionResult
-ProcessWindowsLive::OnDebugException(bool first_chance, const ExceptionRecord &record)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // FIXME: Without this check, occasionally when running the test suite there is
- // an issue where m_session_data can be null. It's not clear how this could happen
- // but it only surfaces while running the test suite. In order to properly diagnose
- // this, we probably need to first figure allow the test suite to print out full
- // lldb logs, and then add logging to the process plugin.
- if (!m_session_data)
- {
- WINERR_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%x at address 0x%I64x, but there is no session.",
- record.GetExceptionCode(), record.GetExceptionAddress());
- return ExceptionResult::SendToApplication;
- }
-
- if (!first_chance)
- {
- // Any second chance exception is an application crash by definition.
- SetPrivateState(eStateCrashed);
- }
-
- ExceptionResult result = ExceptionResult::SendToApplication;
- switch (record.GetExceptionCode())
- {
- case EXCEPTION_BREAKPOINT:
- // Handle breakpoints at the first chance.
- result = ExceptionResult::BreakInDebugger;
-
- if (!m_session_data->m_initial_stop_received)
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
- "Hit loader breakpoint at address 0x%I64x, setting initial stop event.",
- record.GetExceptionAddress());
- m_session_data->m_initial_stop_received = true;
- ::SetEvent(m_session_data->m_initial_stop_event);
- }
- else
- {
- WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
- "Hit non-loader breakpoint at address 0x%I64x.",
- record.GetExceptionAddress());
- }
- SetPrivateState(eStateStopped);
- break;
- case EXCEPTION_SINGLE_STEP:
- result = ExceptionResult::BreakInDebugger;
- SetPrivateState(eStateStopped);
- break;
- default:
- WINLOG_IFANY(WINDOWS_LOG_EXCEPTION,
- "Debugger thread reported exception 0x%x at address 0x%I64x (first_chance=%s)",
- record.GetExceptionCode(), record.GetExceptionAddress(), BOOL_STR(first_chance));
- // For non-breakpoints, give the application a chance to handle the exception first.
- if (first_chance)
- result = ExceptionResult::SendToApplication;
- else
- result = ExceptionResult::BreakInDebugger;
+ProcessWindowsLive::OnDebugException(bool first_chance,
+ const ExceptionRecord &record) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // FIXME: Without this check, occasionally when running the test suite there
+ // is
+ // an issue where m_session_data can be null. It's not clear how this could
+ // happen
+ // but it only surfaces while running the test suite. In order to properly
+ // diagnose
+ // this, we probably need to first figure allow the test suite to print out
+ // full
+ // lldb logs, and then add logging to the process plugin.
+ if (!m_session_data) {
+ WINERR_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception "
+ "0x%x at address 0x%I64x, but there is "
+ "no session.",
+ record.GetExceptionCode(), record.GetExceptionAddress());
+ return ExceptionResult::SendToApplication;
+ }
+
+ if (!first_chance) {
+ // Any second chance exception is an application crash by definition.
+ SetPrivateState(eStateCrashed);
+ }
+
+ ExceptionResult result = ExceptionResult::SendToApplication;
+ switch (record.GetExceptionCode()) {
+ case EXCEPTION_BREAKPOINT:
+ // Handle breakpoints at the first chance.
+ result = ExceptionResult::BreakInDebugger;
+
+ if (!m_session_data->m_initial_stop_received) {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS, "Hit loader breakpoint at address "
+ "0x%I64x, setting initial stop "
+ "event.",
+ record.GetExceptionAddress());
+ m_session_data->m_initial_stop_received = true;
+ ::SetEvent(m_session_data->m_initial_stop_event);
+ } else {
+ WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS,
+ "Hit non-loader breakpoint at address 0x%I64x.",
+ record.GetExceptionAddress());
}
+ SetPrivateState(eStateStopped);
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ result = ExceptionResult::BreakInDebugger;
+ SetPrivateState(eStateStopped);
+ break;
+ default:
+ WINLOG_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception "
+ "0x%x at address 0x%I64x "
+ "(first_chance=%s)",
+ record.GetExceptionCode(), record.GetExceptionAddress(),
+ BOOL_STR(first_chance));
+ // For non-breakpoints, give the application a chance to handle the
+ // exception first.
+ if (first_chance)
+ result = ExceptionResult::SendToApplication;
+ else
+ result = ExceptionResult::BreakInDebugger;
+ }
- return result;
+ return result;
}
-void
-ProcessWindowsLive::OnCreateThread(const HostThread &new_thread)
-{
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
- m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
+void ProcessWindowsLive::OnCreateThread(const HostThread &new_thread) {
+ llvm::sys::ScopedLock lock(m_mutex);
+ const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
+ m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
}
-void
-ProcessWindowsLive::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- // On a forced termination, we may get exit thread events after the session
- // data has been cleaned up.
- if (!m_session_data)
- return;
-
- // A thread may have started and exited before the debugger stopped allowing a refresh.
- // Just remove it from the new threads list in that case.
- auto iter = m_session_data->m_new_threads.find(thread_id);
- if (iter != m_session_data->m_new_threads.end())
- m_session_data->m_new_threads.erase(iter);
- else
- m_session_data->m_exited_threads.insert(thread_id);
+void ProcessWindowsLive::OnExitThread(lldb::tid_t thread_id,
+ uint32_t exit_code) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ // On a forced termination, we may get exit thread events after the session
+ // data has been cleaned up.
+ if (!m_session_data)
+ return;
+
+ // A thread may have started and exited before the debugger stopped allowing a
+ // refresh.
+ // Just remove it from the new threads list in that case.
+ auto iter = m_session_data->m_new_threads.find(thread_id);
+ if (iter != m_session_data->m_new_threads.end())
+ m_session_data->m_new_threads.erase(iter);
+ else
+ m_session_data->m_exited_threads.insert(thread_id);
}
-void
-ProcessWindowsLive::OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr)
-{
- // Confusingly, there is no Target::AddSharedModule. Instead, calling GetSharedModule() with
- // a new module will add it to the module list and return a corresponding ModuleSP.
- Error error;
- ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
- bool load_addr_changed = false;
- module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
+void ProcessWindowsLive::OnLoadDll(const ModuleSpec &module_spec,
+ lldb::addr_t module_addr) {
+ // Confusingly, there is no Target::AddSharedModule. Instead, calling
+ // GetSharedModule() with
+ // a new module will add it to the module list and return a corresponding
+ // ModuleSP.
+ Error error;
+ ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
+ bool load_addr_changed = false;
+ module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
+
+ ModuleList loaded_modules;
+ loaded_modules.Append(module);
+ GetTarget().ModulesDidLoad(loaded_modules);
}
-void
-ProcessWindowsLive::OnUnloadDll(lldb::addr_t module_addr)
-{
- Address resolved_addr;
- if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr))
- {
- ModuleSP module = resolved_addr.GetModule();
- if (module)
- {
- ModuleList unloaded_modules;
- unloaded_modules.Append(module);
- GetTarget().ModulesDidUnload(unloaded_modules, false);
- }
+void ProcessWindowsLive::OnUnloadDll(lldb::addr_t module_addr) {
+ Address resolved_addr;
+ if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) {
+ ModuleSP module = resolved_addr.GetModule();
+ if (module) {
+ ModuleList unloaded_modules;
+ unloaded_modules.Append(module);
+ GetTarget().ModulesDidUnload(unloaded_modules, false);
}
+ }
}
-void
-ProcessWindowsLive::OnDebugString(const std::string &string)
-{
-}
-
-void
-ProcessWindowsLive::OnDebuggerError(const Error &error, uint32_t type)
-{
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (m_session_data->m_initial_stop_received)
- {
- // This happened while debugging. Do we shutdown the debugging session, try to continue,
- // or do something else?
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. Unexpected behavior may result. %s",
- error.GetError(), error.AsCString());
- }
- else
- {
- // If we haven't actually launched the process yet, this was an error launching the
- // process. Set the internal error and signal the initial stop event so that the DoLaunch
- // method wakes up and returns a failure.
- m_session_data->m_launch_error = error;
- ::SetEvent(m_session_data->m_initial_stop_event);
- WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred launching the process before the initial stop. %s",
- error.GetError(), error.AsCString());
- return;
- }
+void ProcessWindowsLive::OnDebugString(const std::string &string) {}
+
+void ProcessWindowsLive::OnDebuggerError(const Error &error, uint32_t type) {
+ llvm::sys::ScopedLock lock(m_mutex);
+
+ if (m_session_data->m_initial_stop_received) {
+ // This happened while debugging. Do we shutdown the debugging session, try
+ // to continue,
+ // or do something else?
+ WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. "
+ "Unexpected behavior may result. %s",
+ error.GetError(), error.AsCString());
+ } else {
+ // If we haven't actually launched the process yet, this was an error
+ // launching the
+ // process. Set the internal error and signal the initial stop event so
+ // that the DoLaunch
+ // method wakes up and returns a failure.
+ m_session_data->m_launch_error = error;
+ ::SetEvent(m_session_data->m_initial_stop_event);
+ WINERR_IFALL(
+ WINDOWS_LOG_PROCESS,
+ "Error %u occurred launching the process before the initial stop. %s",
+ error.GetError(), error.AsCString());
+ return;
+ }
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
index 657877f529b..89d69f6f043 100644
--- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
+++ b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
@@ -19,10 +19,10 @@
// Other libraries and framework includes
#include "ForwardDecl.h"
#include "IDebugDelegate.h"
-#include "lldb/lldb-forward.h"
#include "lldb/Core/Error.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h"
+#include "lldb/lldb-forward.h"
#include "llvm/Support/Mutex.h"
@@ -30,96 +30,100 @@
class ProcessMonitor;
-namespace lldb_private
-{
+namespace lldb_private {
class HostProcess;
class ProcessWindowsData;
-class ProcessWindowsLive : public lldb_private::ProcessWindows, public lldb_private::IDebugDelegate
-{
+class ProcessWindowsLive : public lldb_private::ProcessWindows,
+ public lldb_private::IDebugDelegate {
public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *);
-
- static void
- Initialize();
-
- static void
- Terminate();
-
- static lldb_private::ConstString
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindowsLive(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp);
-
- ~ProcessWindowsLive();
-
- // lldb_private::Process overrides
- lldb_private::ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
-
- lldb_private::Error EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
- lldb_private::Error DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Error DoDetach(bool keep_stopped) override;
- lldb_private::Error DoLaunch(lldb_private::Module *exe_module, lldb_private::ProcessLaunchInfo &launch_info) override;
- lldb_private::Error DoAttachToProcessWithID(lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
- lldb_private::Error DoResume() override;
- lldb_private::Error DoDestroy() override;
- lldb_private::Error DoHalt(bool &caused_stop) override;
-
- void DidLaunch() override;
- void DidAttach(lldb_private::ArchSpec &arch_spec) override;
-
- void RefreshStateAfterStop() override;
-
- bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
- bool
- DestroyRequiresHalt() override
- {
- return false;
- }
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override;
- bool IsAlive() override;
-
- size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, lldb_private::Error &error) override;
- size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, lldb_private::Error &error) override;
- lldb_private::Error GetMemoryRegionInfo(lldb::addr_t vm_addr, lldb_private::MemoryRegionInfo &info) override;
-
- // IDebugDelegate overrides.
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance, const lldb_private::ExceptionRecord &record) override;
- void OnCreateThread(const lldb_private::HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &string) override;
- void OnDebuggerError(const lldb_private::Error &error, uint32_t type) override;
-
- private:
- lldb_private::Error WaitForDebuggerConnection(lldb_private::DebuggerThreadSP debugger,
- lldb_private::HostProcess &process);
-
- llvm::sys::Mutex m_mutex;
-
- // Data for the active debugging session.
- std::unique_ptr<lldb_private::ProcessWindowsData> m_session_data;
+ //------------------------------------------------------------------
+ // Static functions.
+ //------------------------------------------------------------------
+ static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+ lldb::ListenerSP listener_sp,
+ const lldb_private::FileSpec *);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // Constructors and destructors
+ //------------------------------------------------------------------
+ ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+
+ ~ProcessWindowsLive();
+
+ // lldb_private::Process overrides
+ lldb_private::ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ lldb_private::Error
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+ lldb_private::Error
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
+
+ lldb_private::Error DoDetach(bool keep_stopped) override;
+ lldb_private::Error
+ DoLaunch(lldb_private::Module *exe_module,
+ lldb_private::ProcessLaunchInfo &launch_info) override;
+ lldb_private::Error DoAttachToProcessWithID(
+ lldb::pid_t pid,
+ const lldb_private::ProcessAttachInfo &attach_info) override;
+ lldb_private::Error DoResume() override;
+ lldb_private::Error DoDestroy() override;
+ lldb_private::Error DoHalt(bool &caused_stop) override;
+
+ void DidLaunch() override;
+ void DidAttach(lldb_private::ArchSpec &arch_spec) override;
+
+ void RefreshStateAfterStop() override;
+
+ bool CanDebug(lldb::TargetSP target_sp,
+ bool plugin_specified_by_name) override;
+ bool DestroyRequiresHalt() override { return false; }
+ bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
+ lldb_private::ThreadList &new_thread_list) override;
+ bool IsAlive() override;
+
+ size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
+ lldb_private::Error &error) override;
+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
+ lldb_private::Error &error) override;
+ lldb_private::Error
+ GetMemoryRegionInfo(lldb::addr_t vm_addr,
+ lldb_private::MemoryRegionInfo &info) override;
+
+ // IDebugDelegate overrides.
+ void OnExitProcess(uint32_t exit_code) override;
+ void OnDebuggerConnected(lldb::addr_t image_base) override;
+ ExceptionResult
+ OnDebugException(bool first_chance,
+ const lldb_private::ExceptionRecord &record) override;
+ void OnCreateThread(const lldb_private::HostThread &thread) override;
+ void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
+ void OnLoadDll(const lldb_private::ModuleSpec &module_spec,
+ lldb::addr_t module_addr) override;
+ void OnUnloadDll(lldb::addr_t module_addr) override;
+ void OnDebugString(const std::string &string) override;
+ void OnDebuggerError(const lldb_private::Error &error,
+ uint32_t type) override;
+
+private:
+ lldb_private::Error
+ WaitForDebuggerConnection(lldb_private::DebuggerThreadSP debugger,
+ lldb_private::HostProcess &process);
+
+ llvm::sys::Mutex m_mutex;
+
+ // Data for the active debugging session.
+ std::unique_ptr<lldb_private::ProcessWindowsData> m_session_data;
};
-
}
-#endif // liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
+#endif // liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
diff --git a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
index 52b32716e67..b965a6cc3dc 100644
--- a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
+++ b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
@@ -16,9 +16,9 @@
#include "lldb/Host/windows/windows.h"
#include "lldb/Target/RegisterContext.h"
-#include "TargetThreadWindowsLive.h"
#include "ProcessWindows.h"
#include "ProcessWindowsLog.h"
+#include "TargetThreadWindowsLive.h"
#include "UnwindLLDB.h"
#if defined(_WIN64)
@@ -30,118 +30,95 @@
using namespace lldb;
using namespace lldb_private;
-TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread)
- : TargetThreadWindows(process, thread)
- , m_host_thread(thread)
-{
-}
+TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process,
+ const HostThread &thread)
+ : TargetThreadWindows(process, thread), m_host_thread(thread) {}
-TargetThreadWindowsLive::~TargetThreadWindowsLive()
-{
- DestroyThread();
-}
+TargetThreadWindowsLive::~TargetThreadWindowsLive() { DestroyThread(); }
-void
-TargetThreadWindowsLive::RefreshStateAfterStop()
-{
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
+void TargetThreadWindowsLive::RefreshStateAfterStop() {
+ ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
+ SetState(eStateStopped);
+ GetRegisterContext()->InvalidateIfNeeded(false);
}
-void
-TargetThreadWindowsLive::WillResume(lldb::StateType resume_state)
-{
-}
+void TargetThreadWindowsLive::WillResume(lldb::StateType resume_state) {}
-void
-TargetThreadWindowsLive::DidStop()
-{
-}
+void TargetThreadWindowsLive::DidStop() {}
-RegisterContextSP
-TargetThreadWindowsLive::GetRegisterContext()
-{
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
+RegisterContextSP TargetThreadWindowsLive::GetRegisterContext() {
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
- return m_reg_context_sp;
+ return m_reg_context_sp;
}
RegisterContextSP
-TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame)
-{
- return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
+TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame) {
+ return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
}
RegisterContextSP
-TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx)
-{
- if (!m_reg_context_sp)
- {
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine())
- {
- case llvm::Triple::x86:
+TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx) {
+ if (!m_reg_context_sp) {
+ ArchSpec arch = HostInfo::GetArchitecture();
+ switch (arch.GetMachine()) {
+ case llvm::Triple::x86:
#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
+// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
#else
- m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
+ m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
#endif
- break;
- case llvm::Triple::x86_64:
+ break;
+ case llvm::Triple::x86_64:
#if defined(_WIN64)
- m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
+ m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
#else
- // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
+// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug
+// this.
#endif
- default:
- break;
- }
+ default:
+ break;
}
- return m_reg_context_sp;
+ }
+ return m_reg_context_sp;
}
-bool
-TargetThreadWindowsLive::CalculateStopInfo()
-{
- SetStopInfo(m_stop_info_sp);
- return true;
+bool TargetThreadWindowsLive::CalculateStopInfo() {
+ SetStopInfo(m_stop_info_sp);
+ return true;
}
-Unwind *
-TargetThreadWindowsLive::GetUnwinder()
-{
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
- if (m_unwinder_ap.get() == NULL)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
+Unwind *TargetThreadWindowsLive::GetUnwinder() {
+ // FIXME: Implement an unwinder based on the Windows unwinder exposed through
+ // DIA SDK.
+ if (m_unwinder_ap.get() == NULL)
+ m_unwinder_ap.reset(new UnwindLLDB(*this));
+ return m_unwinder_ap.get();
}
-bool
-TargetThreadWindowsLive::DoResume()
-{
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return true;
-
- if (resume_state == eStateStepping)
- {
- uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
- flags_value |= 0x100; // Set the trap flag on the CPU
- GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
- }
-
- if (resume_state == eStateStepping || resume_state == eStateRunning)
- {
- DWORD previous_suspend_count = 0;
- HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
- do
- {
- previous_suspend_count = ::ResumeThread(thread_handle);
- } while (previous_suspend_count > 0);
- }
+bool TargetThreadWindowsLive::DoResume() {
+ StateType resume_state = GetTemporaryResumeState();
+ StateType current_state = GetState();
+ if (resume_state == current_state)
return true;
+
+ if (resume_state == eStateStepping) {
+ uint32_t flags_index =
+ GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ uint64_t flags_value =
+ GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
+ flags_value |= 0x100; // Set the trap flag on the CPU
+ GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
+ }
+
+ if (resume_state == eStateStepping || resume_state == eStateRunning) {
+ DWORD previous_suspend_count = 0;
+ HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
+ do {
+ previous_suspend_count = ::ResumeThread(thread_handle);
+ } while (previous_suspend_count > 0);
+ }
+ return true;
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
index 15262b9e942..47e09247a63 100644
--- a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
+++ b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h
@@ -10,45 +10,40 @@
#ifndef liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
#define liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
-#include "lldb/lldb-forward.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Thread.h"
+#include "lldb/lldb-forward.h"
#include "Plugins/Process/Windows/Common/TargetThreadWindows.h"
-namespace lldb_private
-{
+namespace lldb_private {
class ProcessWindows;
class HostThread;
class StackFrame;
-class TargetThreadWindowsLive : public lldb_private::TargetThreadWindows
-{
- public:
- TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread);
- virtual ~TargetThreadWindowsLive();
-
- // lldb_private::Thread overrides
- void RefreshStateAfterStop() override;
- void WillResume(lldb::StateType resume_state) override;
- void DidStop() override;
- lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- bool DoResume();
-
- HostThread
- GetHostThread() const
- {
- return m_host_thread;
- }
-
- private:
- lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
-
- HostThread m_host_thread;
+class TargetThreadWindowsLive : public lldb_private::TargetThreadWindows {
+public:
+ TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread);
+ virtual ~TargetThreadWindowsLive();
+
+ // lldb_private::Thread overrides
+ void RefreshStateAfterStop() override;
+ void WillResume(lldb::StateType resume_state) override;
+ void DidStop() override;
+ lldb::RegisterContextSP GetRegisterContext() override;
+ lldb::RegisterContextSP
+ CreateRegisterContextForFrame(StackFrame *frame) override;
+ bool CalculateStopInfo() override;
+ Unwind *GetUnwinder() override;
+
+ bool DoResume();
+
+ HostThread GetHostThread() const { return m_host_thread; }
+
+private:
+ lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
+
+ HostThread m_host_thread;
};
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp b/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
index e74647ab68f..33237110991 100644
--- a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
+++ b/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.cpp
@@ -7,165 +7,160 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
-#include "lldb-x86-register-enums.h"
#include "RegisterContextWindowsLive_x64.h"
#include "TargetThreadWindows.h"
+#include "lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
using namespace lldb;
using namespace lldb_private;
-RegisterContextWindowsLive_x64::RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows_x64(thread, concrete_frame_idx)
-{
-}
-
-RegisterContextWindowsLive_x64::~RegisterContextWindowsLive_x64()
-{
-}
+RegisterContextWindowsLive_x64::RegisterContextWindowsLive_x64(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextWindows_x64(thread, concrete_frame_idx) {}
+RegisterContextWindowsLive_x64::~RegisterContextWindowsLive_x64() {}
-bool
-RegisterContextWindowsLive_x64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
-{
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindowsLive_x64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (!CacheAllRegisterValues())
+ return false;
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- reg_value.SetUInt64(m_context.Rax);
- break;
- case lldb_rbx_x86_64:
- reg_value.SetUInt64(m_context.Rbx);
- break;
- case lldb_rcx_x86_64:
- reg_value.SetUInt64(m_context.Rcx);
- break;
- case lldb_rdx_x86_64:
- reg_value.SetUInt64(m_context.Rdx);
- break;
- case lldb_rdi_x86_64:
- reg_value.SetUInt64(m_context.Rdi);
- break;
- case lldb_rsi_x86_64:
- reg_value.SetUInt64(m_context.Rsi);
- break;
- case lldb_r8_x86_64:
- reg_value.SetUInt64(m_context.R8);
- break;
- case lldb_r9_x86_64:
- reg_value.SetUInt64(m_context.R9);
- break;
- case lldb_r10_x86_64:
- reg_value.SetUInt64(m_context.R10);
- break;
- case lldb_r11_x86_64:
- reg_value.SetUInt64(m_context.R11);
- break;
- case lldb_r12_x86_64:
- reg_value.SetUInt64(m_context.R12);
- break;
- case lldb_r13_x86_64:
- reg_value.SetUInt64(m_context.R13);
- break;
- case lldb_r14_x86_64:
- reg_value.SetUInt64(m_context.R14);
- break;
- case lldb_r15_x86_64:
- reg_value.SetUInt64(m_context.R15);
- break;
- case lldb_rbp_x86_64:
- reg_value.SetUInt64(m_context.Rbp);
- break;
- case lldb_rsp_x86_64:
- reg_value.SetUInt64(m_context.Rsp);
- break;
- case lldb_rip_x86_64:
- reg_value.SetUInt64(m_context.Rip);
- break;
- case lldb_rflags_x86_64:
- reg_value.SetUInt64(m_context.EFlags);
- break;
- }
- return true;
+ switch (reg_info->kinds[eRegisterKindLLDB]) {
+ case lldb_rax_x86_64:
+ reg_value.SetUInt64(m_context.Rax);
+ break;
+ case lldb_rbx_x86_64:
+ reg_value.SetUInt64(m_context.Rbx);
+ break;
+ case lldb_rcx_x86_64:
+ reg_value.SetUInt64(m_context.Rcx);
+ break;
+ case lldb_rdx_x86_64:
+ reg_value.SetUInt64(m_context.Rdx);
+ break;
+ case lldb_rdi_x86_64:
+ reg_value.SetUInt64(m_context.Rdi);
+ break;
+ case lldb_rsi_x86_64:
+ reg_value.SetUInt64(m_context.Rsi);
+ break;
+ case lldb_r8_x86_64:
+ reg_value.SetUInt64(m_context.R8);
+ break;
+ case lldb_r9_x86_64:
+ reg_value.SetUInt64(m_context.R9);
+ break;
+ case lldb_r10_x86_64:
+ reg_value.SetUInt64(m_context.R10);
+ break;
+ case lldb_r11_x86_64:
+ reg_value.SetUInt64(m_context.R11);
+ break;
+ case lldb_r12_x86_64:
+ reg_value.SetUInt64(m_context.R12);
+ break;
+ case lldb_r13_x86_64:
+ reg_value.SetUInt64(m_context.R13);
+ break;
+ case lldb_r14_x86_64:
+ reg_value.SetUInt64(m_context.R14);
+ break;
+ case lldb_r15_x86_64:
+ reg_value.SetUInt64(m_context.R15);
+ break;
+ case lldb_rbp_x86_64:
+ reg_value.SetUInt64(m_context.Rbp);
+ break;
+ case lldb_rsp_x86_64:
+ reg_value.SetUInt64(m_context.Rsp);
+ break;
+ case lldb_rip_x86_64:
+ reg_value.SetUInt64(m_context.Rip);
+ break;
+ case lldb_rflags_x86_64:
+ reg_value.SetUInt64(m_context.EFlags);
+ break;
+ }
+ return true;
}
-bool
-RegisterContextWindowsLive_x64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindowsLive_x64::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ // Since we cannot only write a single register value to the inferior, we need
+ // to make sure
+ // our cached copy of the register values are fresh. Otherwise when writing
+ // EAX, for example,
+ // we may also overwrite some other register with a stale value.
+ if (!CacheAllRegisterValues())
+ return false;
- switch (reg_info->kinds[eRegisterKindLLDB])
- {
- case lldb_rax_x86_64:
- m_context.Rax = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_context.Rbx = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_context.Rcx = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_context.Rdx = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_context.Rdi = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_context.Rsi = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_context.R8 = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_context.R9 = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_context.R10 = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_context.R11 = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_context.R12 = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_context.R13 = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_context.R14 = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_context.R15 = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_context.Rbp = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_context.Rsp = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_context.Rip = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_context.EFlags = reg_value.GetAsUInt64();
- break;
- }
+ switch (reg_info->kinds[eRegisterKindLLDB]) {
+ case lldb_rax_x86_64:
+ m_context.Rax = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbx_x86_64:
+ m_context.Rbx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rcx_x86_64:
+ m_context.Rcx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdx_x86_64:
+ m_context.Rdx = reg_value.GetAsUInt64();
+ break;
+ case lldb_rdi_x86_64:
+ m_context.Rdi = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsi_x86_64:
+ m_context.Rsi = reg_value.GetAsUInt64();
+ break;
+ case lldb_r8_x86_64:
+ m_context.R8 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r9_x86_64:
+ m_context.R9 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r10_x86_64:
+ m_context.R10 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r11_x86_64:
+ m_context.R11 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r12_x86_64:
+ m_context.R12 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r13_x86_64:
+ m_context.R13 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r14_x86_64:
+ m_context.R14 = reg_value.GetAsUInt64();
+ break;
+ case lldb_r15_x86_64:
+ m_context.R15 = reg_value.GetAsUInt64();
+ break;
+ case lldb_rbp_x86_64:
+ m_context.Rbp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rsp_x86_64:
+ m_context.Rsp = reg_value.GetAsUInt64();
+ break;
+ case lldb_rip_x86_64:
+ m_context.Rip = reg_value.GetAsUInt64();
+ break;
+ case lldb_rflags_x86_64:
+ m_context.EFlags = reg_value.GetAsUInt64();
+ break;
+ }
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+ // Physically update the registers in the target process.
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ return ::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h b/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
index bd250a994d3..84425c4fa82 100644
--- a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
+++ b/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindowsLive_x64.h
@@ -10,30 +10,30 @@
#ifndef liblldb_RegisterContextWindowsLive_x64_H_
#define liblldb_RegisterContextWindowsLive_x64_H_
-#include "lldb/lldb-forward.h"
#include "../../Common/x64/RegisterContextWindows_x64.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindowsLive_x64 : public RegisterContextWindows_x64
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindowsLive_x64 : public RegisterContextWindows_x64 {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindowsLive_x64();
+ virtual ~RegisterContextWindowsLive_x64();
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override;
+ //------------------------------------------------------------------
+ // Subclasses must override these functions
+ //------------------------------------------------------------------
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
};
}
diff --git a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
index f2decc72d16..0e7412051ae 100644
--- a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
+++ b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp
@@ -1,4 +1,5 @@
-//===-- RegisterContextWindowsLive_x86.cpp ------------------------*- C++ -*-===//
+//===-- RegisterContextWindowsLive_x86.cpp ------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,94 +8,101 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-private-types.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/lldb-private-types.h"
-#include "lldb-x86-register-enums.h"
#include "ProcessWindowsLog.h"
#include "RegisterContextWindowsLive_x86.h"
#include "TargetThreadWindows.h"
+#include "lldb-x86-register-enums.h"
#include "llvm/ADT/STLExtras.h"
using namespace lldb;
-namespace lldb_private
-{
+namespace lldb_private {
-RegisterContextWindowsLive_x86::RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows_x86(thread, concrete_frame_idx)
-{
-}
-
-RegisterContextWindowsLive_x86::~RegisterContextWindowsLive_x86()
-{
-}
+RegisterContextWindowsLive_x86::RegisterContextWindowsLive_x86(
+ Thread &thread, uint32_t concrete_frame_idx)
+ : RegisterContextWindows_x86(thread, concrete_frame_idx) {}
+RegisterContextWindowsLive_x86::~RegisterContextWindowsLive_x86() {}
-bool
-RegisterContextWindowsLive_x86::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)
-{
- // Since we cannot only write a single register value to the inferior, we need to make sure
- // our cached copy of the register values are fresh. Otherwise when writing EAX, for example,
- // we may also overwrite some other register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
+bool RegisterContextWindowsLive_x86::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ // Since we cannot only write a single register value to the inferior, we need
+ // to make sure
+ // our cached copy of the register values are fresh. Otherwise when writing
+ // EAX, for example,
+ // we may also overwrite some other register with a stale value.
+ if (!CacheAllRegisterValues())
+ return false;
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg)
- {
- case lldb_eax_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX", reg_value.GetAsUInt32());
- m_context.Eax = reg_value.GetAsUInt32();
- break;
- case lldb_ebx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX", reg_value.GetAsUInt32());
- m_context.Ebx = reg_value.GetAsUInt32();
- break;
- case lldb_ecx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX", reg_value.GetAsUInt32());
- m_context.Ecx = reg_value.GetAsUInt32();
- break;
- case lldb_edx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX", reg_value.GetAsUInt32());
- m_context.Edx = reg_value.GetAsUInt32();
- break;
- case lldb_edi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI", reg_value.GetAsUInt32());
- m_context.Edi = reg_value.GetAsUInt32();
- break;
- case lldb_esi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI", reg_value.GetAsUInt32());
- m_context.Esi = reg_value.GetAsUInt32();
- break;
- case lldb_ebp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP", reg_value.GetAsUInt32());
- m_context.Ebp = reg_value.GetAsUInt32();
- break;
- case lldb_esp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP", reg_value.GetAsUInt32());
- m_context.Esp = reg_value.GetAsUInt32();
- break;
- case lldb_eip_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP", reg_value.GetAsUInt32());
- m_context.Eip = reg_value.GetAsUInt32();
- break;
- case lldb_eflags_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS", reg_value.GetAsUInt32());
- m_context.EFlags = reg_value.GetAsUInt32();
- break;
- default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to unknown register %u", reg_value.GetAsUInt32(),
- reg);
- }
+ uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ switch (reg) {
+ case lldb_eax_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX",
+ reg_value.GetAsUInt32());
+ m_context.Eax = reg_value.GetAsUInt32();
+ break;
+ case lldb_ebx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX",
+ reg_value.GetAsUInt32());
+ m_context.Ebx = reg_value.GetAsUInt32();
+ break;
+ case lldb_ecx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX",
+ reg_value.GetAsUInt32());
+ m_context.Ecx = reg_value.GetAsUInt32();
+ break;
+ case lldb_edx_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX",
+ reg_value.GetAsUInt32());
+ m_context.Edx = reg_value.GetAsUInt32();
+ break;
+ case lldb_edi_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI",
+ reg_value.GetAsUInt32());
+ m_context.Edi = reg_value.GetAsUInt32();
+ break;
+ case lldb_esi_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI",
+ reg_value.GetAsUInt32());
+ m_context.Esi = reg_value.GetAsUInt32();
+ break;
+ case lldb_ebp_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP",
+ reg_value.GetAsUInt32());
+ m_context.Ebp = reg_value.GetAsUInt32();
+ break;
+ case lldb_esp_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP",
+ reg_value.GetAsUInt32());
+ m_context.Esp = reg_value.GetAsUInt32();
+ break;
+ case lldb_eip_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP",
+ reg_value.GetAsUInt32());
+ m_context.Eip = reg_value.GetAsUInt32();
+ break;
+ case lldb_eflags_i386:
+ WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS",
+ reg_value.GetAsUInt32());
+ m_context.EFlags = reg_value.GetAsUInt32();
+ break;
+ default:
+ WINWARN_IFALL(WINDOWS_LOG_REGISTERS,
+ "Write value 0x%x to unknown register %u",
+ reg_value.GetAsUInt32(), reg);
+ }
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
+ // Physically update the registers in the target process.
+ TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
+ return ::SetThreadContext(
+ wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
-} // namespace lldb_private
+} // namespace lldb_private
diff --git a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
index 9554f017408..e9b8ecd58f5 100644
--- a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
+++ b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h
@@ -10,27 +10,25 @@
#ifndef liblldb_RegisterContextWindowsLive_x86_H_
#define liblldb_RegisterContextWindowsLive_x86_H_
-#include "lldb/lldb-forward.h"
#include "../../Common/x86/RegisterContextWindows_x86.h"
+#include "lldb/lldb-forward.h"
-namespace lldb_private
-{
+namespace lldb_private {
class Thread;
-class RegisterContextWindowsLive_x86 : public RegisterContextWindows_x86
-{
- public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx);
+class RegisterContextWindowsLive_x86 : public RegisterContextWindows_x86 {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx);
- virtual ~RegisterContextWindowsLive_x86();
+ virtual ~RegisterContextWindowsLive_x86();
- bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override;
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
};
-
}
#endif // #ifndef liblldb_RegisterContextWindowsLive_x86_H_
OpenPOWER on IntegriCloud