When a process stops, set the StopInfo object on Windows.
authorZachary Turner <zturner@google.com>
Tue, 25 Nov 2014 19:03:19 +0000 (19:03 +0000)
committerZachary Turner <zturner@google.com>
Tue, 25 Nov 2014 19:03:19 +0000 (19:03 +0000)
llvm-svn: 222776

lldb/source/Plugins/Process/Windows/ProcessWindows.cpp
lldb/source/Plugins/Process/Windows/ProcessWindows.h
lldb/source/Plugins/Process/Windows/RegisterContextWindows_x86.cpp

index c55aa7116a4a5001dd107c548d4ae7345e324144..c43b3729b2663430c2a74957375f651f52314e3a 100644 (file)
@@ -29,6 +29,8 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/FileAction.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StopInfo.h"
 #include "lldb/Target/Target.h"
 
 #include "DebuggerThread.h"
@@ -62,6 +64,7 @@ class ProcessWindowsData
     std::shared_ptr<lldb_private::ExceptionRecord> m_active_exception;
     lldb_private::Error m_launch_error;
     lldb_private::DebuggerThreadSP m_debugger;
+    StopInfoSP m_pending_stop_info;
     HANDLE m_initial_stop_event;
     bool m_initial_stop_received;
     std::map<lldb::tid_t, HostThread> m_new_threads;
@@ -275,6 +278,30 @@ void
 ProcessWindows::RefreshStateAfterStop()
 {
     m_thread_list.RefreshStateAfterStop();
+
+    if (m_session_data->m_active_exception)
+    {
+        StopInfoSP stop_info;
+        ThreadSP stop_thread = m_thread_list.GetSelectedThread();
+        RegisterContextSP register_context = stop_thread->GetRegisterContext();
+
+        ExceptionRecord &exception = *m_session_data->m_active_exception;
+        if (exception.GetExceptionCode() == EXCEPTION_BREAKPOINT)
+        {
+            uint64_t pc = register_context->GetPC();
+            BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
+            lldb::break_id_t break_id = LLDB_INVALID_BREAK_ID;
+            bool should_stop = true;
+            if (site)
+            {
+                should_stop = site->ValidForThisThread(stop_thread.get());
+                break_id = site->GetID();
+            }
+
+            stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, break_id, should_stop);
+            stop_thread->SetStopInfo(stop_info);
+        }
+    }
 }
 
 bool
@@ -310,6 +337,15 @@ ProcessWindows::DoHalt(bool &caused_stop)
     return error;
 }
 
+void ProcessWindows::DidLaunch()
+{
+    StateType state = GetPrivateState();
+    // 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_launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
+        RefreshStateAfterStop();
+}
+
 size_t
 ProcessWindows::DoReadMemory(lldb::addr_t vm_addr,
                              void *buf,
@@ -406,6 +442,7 @@ ProcessWindows::OnDebugException(bool first_chance, const ExceptionRecord &recor
                 m_session_data->m_initial_stop_received = true;
                 ::SetEvent(m_session_data->m_initial_stop_event);
             }
+
             break;
         default:
             // For non-breakpoints, give the application a chance to handle the exception first.
index e482f9f18d0e1155e8502b254af770065349e4fa..964f1518443386b79686510a1967654ed2fbebeb 100644 (file)
@@ -77,6 +77,8 @@ public:
     lldb_private::Error DoDestroy() override;
     lldb_private::Error DoHalt(bool &caused_stop) override;
 
+    void DidLaunch() override;
+
     void RefreshStateAfterStop() override;
     lldb::addr_t GetImageInfoAddress() override;
 
index cdd9774a694dd64ca72fd2f70c9ec6991fddabd3..f4bef83557be6e0da7b35e21576e0e14120dc179 100644 (file)
@@ -94,6 +94,7 @@ RegisterSet g_register_sets[] = {
 RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx)
     : RegisterContext(thread, concrete_frame_idx)
     , m_context_stale(true)
+    , m_context_ptr(nullptr)
 {
 }