[Lldb-commits] [lldb] r221642 - [ProcessWindows] Implement breakpoint stop / resume on Windows.
Zachary Turner
zturner at google.com
Mon Nov 10 16:00:14 PST 2014
Author: zturner
Date: Mon Nov 10 18:00:14 2014
New Revision: 221642
URL: http://llvm.org/viewvc/llvm-project?rev=221642&view=rev
Log:
[ProcessWindows] Implement breakpoint stop / resume on Windows.
This patch implements basic support for stopping at breakpoints
and resuming later. While a breakpoint is stopped at, LLDB will
cease to process events in the debug loop, effectively suspending
the process, and then resume later when ProcessWindows::DoResume
is called.
As a side effect, this also correctly handles the loader breakpoint
(i.e. the initial stop) so that LLDB goes through the correct state
sequence during the initial process launch.
Added:
lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h
Modified:
lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp
lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.h
lldb/trunk/source/Plugins/Process/Windows/ForwardDecl.h
lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h
lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp
lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h
lldb/trunk/source/Plugins/Process/Windows/ProcessMessages.h
lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h
Modified: lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.cpp Mon Nov 10 18:00:14 2014
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "DebuggerThread.h"
+#include "ExceptionRecord.h"
#include "IDebugDelegate.h"
#include "ProcessMessages.h"
@@ -98,6 +99,12 @@ DebuggerThread::DebuggerThreadRoutine(co
}
void
+DebuggerThread::ContinueAsyncException(ExceptionResult result)
+{
+ m_exception.SetValue(result, eBroadcastAlways);
+}
+
+void
DebuggerThread::DebugLoop()
{
DEBUG_EVENT dbe = {0};
@@ -108,8 +115,17 @@ DebuggerThread::DebugLoop()
switch (dbe.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
- continue_status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
+ {
+ ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
+ m_exception.SetValue(status, eBroadcastNever);
+ m_exception.WaitForValueNotEqualTo(ExceptionResult::WillHandle, status);
+
+ if (status == ExceptionResult::Handled)
+ continue_status = DBG_CONTINUE;
+ else if (status == ExceptionResult::NotHandled)
+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
+ }
case CREATE_THREAD_DEBUG_EVENT:
continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
break;
@@ -143,10 +159,12 @@ DebuggerThread::DebugLoop()
}
}
-DWORD
+ExceptionResult
DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
{
- return DBG_CONTINUE;
+ bool first_chance = (info.dwFirstChance != 0);
+ ProcessMessageException message(m_process, ExceptionRecord(info.ExceptionRecord), first_chance);
+ return m_debug_delegate->OnDebugException(message);
}
DWORD
Modified: lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.h?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/DebuggerThread.h Mon Nov 10 18:00:14 2014
@@ -13,6 +13,7 @@
#include "ForwardDecl.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Predicate.h"
#include "lldb/Host/windows/windows.h"
#include <memory>
@@ -45,9 +46,11 @@ class DebuggerThread : public std::enabl
return m_main_thread;
}
+ void ContinueAsyncException(ExceptionResult result);
+
private:
void DebugLoop();
- DWORD HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id);
+ 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);
@@ -63,6 +66,10 @@ class DebuggerThread : public std::enabl
HostThread m_main_thread; // The main thread of the inferior.
HANDLE m_image_file; // The image file of the process being debugged.
+ Predicate<ExceptionResult> m_exception; // A predicate which gets signalled when an exception
+ // is finished processing and the debug loop can be
+ // continued.
+
static lldb::thread_result_t DebuggerThreadRoutine(void *data);
lldb::thread_result_t DebuggerThreadRoutine(const ProcessLaunchInfo &launch_info);
};
Added: lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h?rev=221642&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h (added)
+++ lldb/trunk/source/Plugins/Process/Windows/ExceptionRecord.h Mon Nov 10 18:00:14 2014
@@ -0,0 +1,74 @@
+//===-- ExceptionRecord.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Plugins_Process_Windows_ExceptionRecord_H_
+#define liblldb_Plugins_Process_Windows_ExceptionRecord_H_
+
+#include "ForwardDecl.h"
+
+#include "lldb/lldb-forward.h"
+#include "lldb/Host/windows/windows.h"
+
+#include <memory>
+#include <vector>
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+// ExceptionRecord
+//
+// ExceptionRecord defines an interface which allows implementors to receive
+// notification of events that happen in a debugged process.
+//----------------------------------------------------------------------
+class ExceptionRecord
+{
+ public:
+ explicit ExceptionRecord(const EXCEPTION_RECORD &record)
+ {
+ m_code = record.ExceptionCode;
+ m_continuable = (record.ExceptionFlags == 0);
+ if (record.ExceptionRecord)
+ m_next_exception.reset(new ExceptionRecord(*record.ExceptionRecord));
+ m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
+ m_arguments.assign(record.ExceptionInformation, record.ExceptionInformation + record.NumberParameters);
+ }
+ virtual ~ExceptionRecord() {}
+
+ DWORD
+ GetExceptionCode() const
+ {
+ return m_code;
+ }
+ bool
+ IsContinuable() const
+ {
+ return m_continuable;
+ }
+ const ExceptionRecord *
+ GetNextException() const
+ {
+ return m_next_exception.get();
+ }
+ lldb::addr_t
+ GetExceptionAddress() const
+ {
+ return m_exception_addr;
+ }
+
+ private:
+ DWORD m_code;
+ bool m_continuable;
+ std::shared_ptr<ExceptionRecord> m_next_exception;
+ lldb::addr_t m_exception_addr;
+ std::vector<ULONG_PTR> m_arguments;
+};
+}
+
+#endif
Modified: lldb/trunk/source/Plugins/Process/Windows/ForwardDecl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ForwardDecl.h?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ForwardDecl.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ForwardDecl.h Mon Nov 10 18:00:14 2014
@@ -14,12 +14,25 @@ class ProcessWindows;
#include <memory>
+// ExceptionResult is returned by the debug delegate to specify how it processed
+// the exception.
+enum class ExceptionResult
+{
+ Handled, // The delegate handled the exception. Continue.
+ NotHandled, // The delegate did not handle the exception. Keep
+ // searching.
+ WillHandle // The delegate will handle the exception. Do not
+ // process further debug events until it finishes.
+};
+
namespace lldb_private
{
-class IDebugDelegate;
+class IDebugDelegate;
class DebuggerThread;
+class ExceptionRecord;
+
// Process message forward declarations.
class ProcessMessageBase;
class ProcessMessageExitProcess;
Modified: lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/IDebugDelegate.h Mon Nov 10 18:00:14 2014
@@ -28,7 +28,7 @@ class IDebugDelegate
virtual void OnExitProcess(const ProcessMessageExitProcess &message) = 0;
virtual void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) = 0;
- virtual void OnDebugException(const ProcessMessageException &message) = 0;
+ virtual ExceptionResult OnDebugException(const ProcessMessageException &message) = 0;
virtual void OnCreateThread(const ProcessMessageCreateThread &message) = 0;
virtual void OnExitThread(const ProcessMessageExitThread &message) = 0;
virtual void OnLoadDll(const ProcessMessageLoadDll &message) = 0;
Modified: lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.cpp Mon Nov 10 18:00:14 2014
@@ -30,10 +30,10 @@ LocalDebugDelegate::OnDebuggerConnected(
((ProcessWindows &)*m_process).OnDebuggerConnected(message);
}
-void
+ExceptionResult
LocalDebugDelegate::OnDebugException(const ProcessMessageException &message)
{
- ((ProcessWindows &)*m_process).OnDebugException(message);
+ return ((ProcessWindows &)*m_process).OnDebugException(message);
}
void
Modified: lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/LocalDebugDelegate.h Mon Nov 10 18:00:14 2014
@@ -44,7 +44,7 @@ class LocalDebugDelegate : public IDebug
void OnExitProcess(const ProcessMessageExitProcess &message) override;
void OnDebuggerConnected(const ProcessMessageDebuggerConnected &message) override;
- void OnDebugException(const ProcessMessageException &message) override;
+ ExceptionResult OnDebugException(const ProcessMessageException &message) override;
void OnCreateThread(const ProcessMessageCreateThread &message) override;
void OnExitThread(const ProcessMessageExitThread &message) override;
void OnLoadDll(const ProcessMessageLoadDll &message) override;
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessMessages.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessMessages.h?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessMessages.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessMessages.h Mon Nov 10 18:00:14 2014
@@ -10,9 +10,13 @@
#ifndef liblldb_Plugins_Process_Windows_ProcessMessages_H_
#define liblldb_Plugins_Process_Windows_ProcessMessages_H_
+#include "ExceptionRecord.h"
+
#include "lldb/Core/Error.h"
#include "lldb/Host/HostProcess.h"
+#include <memory>
+
namespace lldb_private
{
@@ -51,6 +55,32 @@ class ProcessMessageDebuggerConnected :
}
};
+class ProcessMessageException : public ProcessMessageBase
+{
+ public:
+ ProcessMessageException(const HostProcess &process, const ExceptionRecord &exception, bool first_chance)
+ : ProcessMessageBase(process)
+ , m_exception(exception)
+ , m_first_chance(first_chance)
+ {
+ }
+
+ bool
+ IsFirstChance() const
+ {
+ return m_first_chance;
+ }
+ const ExceptionRecord &
+ GetExceptionRecord() const
+ {
+ return m_exception;
+ }
+
+ private:
+ bool m_first_chance;
+ ExceptionRecord m_exception;
+};
+
class ProcessMessageExitProcess : public ProcessMessageBase
{
public:
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.cpp Mon Nov 10 18:00:14 2014
@@ -28,6 +28,7 @@
#include "lldb/Target/Target.h"
#include "DebuggerThread.h"
+#include "ExceptionRecord.h"
#include "LocalDebugDelegate.h"
#include "ProcessMessages.h"
#include "ProcessWindows.h"
@@ -144,6 +145,7 @@ ProcessWindows::DoLaunch(Module *exe_mod
launch_info.SetProcessID(process.GetProcessId());
SetID(process.GetProcessId());
+
return result;
}
@@ -151,6 +153,11 @@ Error
ProcessWindows::DoResume()
{
Error error;
+ if (!m_active_exception)
+ return error;
+
+ m_debugger->ContinueAsyncException(ExceptionResult::Handled);
+ SetPrivateState(eStateRunning);
return error;
}
@@ -240,6 +247,7 @@ void
ProcessWindows::OnExitProcess(const ProcessMessageExitProcess &message)
{
SetProcessExitStatus(nullptr, GetID(), true, 0, message.GetExitCode());
+ SetPrivateState(eStateExited);
}
void
@@ -248,9 +256,20 @@ ProcessWindows::OnDebuggerConnected(cons
::SetEvent(m_data_up->m_launched_event);
}
-void
+ExceptionResult
ProcessWindows::OnDebugException(const ProcessMessageException &message)
{
+ ExceptionResult result = ExceptionResult::Handled;
+ const ExceptionRecord &record = message.GetExceptionRecord();
+ m_active_exception.reset(new ExceptionRecord(record));
+ switch (record.GetExceptionCode())
+ {
+ case EXCEPTION_BREAKPOINT:
+ SetPrivateState(eStateStopped);
+ result = ExceptionResult::WillHandle;
+ break;
+ }
+ return result;
}
void
Modified: lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h?rev=221642&r1=221641&r2=221642&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/ProcessWindows.h Mon Nov 10 18:00:14 2014
@@ -117,7 +117,7 @@ public:
// IDebugDelegate overrides.
virtual void OnExitProcess(const lldb_private::ProcessMessageExitProcess &message) override;
virtual void OnDebuggerConnected(const lldb_private::ProcessMessageDebuggerConnected &message) override;
- virtual void OnDebugException(const lldb_private::ProcessMessageException &message) override;
+ virtual ExceptionResult OnDebugException(const lldb_private::ProcessMessageException &message) override;
virtual void OnCreateThread(const lldb_private::ProcessMessageCreateThread &message) override;
virtual void OnExitThread(const lldb_private::ProcessMessageExitThread &message) override;
virtual void OnLoadDll(const lldb_private::ProcessMessageLoadDll &message) override;
@@ -126,6 +126,7 @@ public:
virtual void OnDebuggerError(const lldb_private::ProcessMessageDebuggerError &message) override;
private:
+ std::shared_ptr<lldb_private::ExceptionRecord> m_active_exception;
std::unique_ptr<lldb_private::ProcessWindowsData> m_data_up;
lldb_private::Error m_launch_error;
lldb_private::DebuggerThreadSP m_debugger;
More information about the lldb-commits
mailing list