[Lldb-commits] [lldb] r237781 - Fix handling of hijacked events in synchronous mode

Ilia K ki.stfu at gmail.com
Wed May 20 03:15:50 PDT 2015


Author: ki.stfu
Date: Wed May 20 05:15:47 2015
New Revision: 237781

URL: http://llvm.org/viewvc/llvm-project?rev=237781&view=rev
Log:
Fix handling of hijacked events in synchronous mode

Summary:
This patch includes the following changes:
* Fix Target::Launch to handle hijacked event in synchronous mode
* Improve MiStartupOptionsTestCase tests to expect *stopped (MI)
* Add SBProcess::GetStopEventForStopID
* Add ProcessModID::SetStopEventForLastNaturalStopID/GetStopEventForStopID
* Add const qualifier to ProcessModID::GetLastNaturalStopID
* Add SBProcess::GetStopEventForStopID
* Don't broadcast hijacked event in Target::Launch
* Add CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent/RebroadcastStopEvent

Test Plan: ./dotest.py -v --executable $BUILDDIR/bin/lldb tools/lldb-mi/startup_options/

Reviewers: zturner, jingham, clayborg, abidh

Reviewed By: clayborg

Subscribers: abidh, zturner, lldb-commits, clayborg, jingham

Differential Revision: http://reviews.llvm.org/D9371

Modified:
    lldb/trunk/include/lldb/API/SBProcess.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/source/API/SBProcess.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
    lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp
    lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h
    lldb/trunk/tools/lldb-mi/MIDriver.cpp

Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Wed May 20 05:15:47 2015
@@ -229,7 +229,22 @@ public:
     
     uint32_t
     GetStopID(bool include_expression_stops = false);
-    
+
+    //------------------------------------------------------------------
+    /// Gets the stop event corresponding to stop ID.
+    //
+    /// Note that it wasn't fully implemented and tracks only the stop
+    /// event for the last natural stop ID.
+    ///
+    /// @param [in] stop_id
+    ///   The ID of the stop event to return.
+    ///
+    /// @return
+    ///   The stop event corresponding to stop ID.
+    //------------------------------------------------------------------
+    lldb::SBEvent
+    GetStopEventForStopID(uint32_t stop_id);
+
     size_t
     ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
 

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Wed May 20 05:15:47 2015
@@ -685,7 +685,20 @@ public:
         else
             m_running_user_expression--;
     }
-    
+
+    void
+    SetStopEventForLastNaturalStopID (lldb::EventSP event_sp)
+    {
+        m_last_natural_stop_event = event_sp;
+    }
+
+    lldb::EventSP GetStopEventForStopID (uint32_t stop_id) const
+    {
+        if (stop_id == m_last_natural_stop_id)
+            return m_last_natural_stop_event;
+        return lldb::EventSP();
+    }
+
 private:
     uint32_t m_stop_id;
     uint32_t m_last_natural_stop_id;
@@ -693,6 +706,7 @@ private:
     uint32_t m_memory_id;
     uint32_t m_last_user_expression_resume;
     uint32_t m_running_user_expression;
+    lldb::EventSP m_last_natural_stop_event;
 };
 inline bool operator== (const ProcessModID &lhs, const ProcessModID &rhs)
 {
@@ -1954,11 +1968,17 @@ public:
     }
     
     uint32_t
-    GetLastNaturalStopID()
+    GetLastNaturalStopID() const
     {
         return m_mod_id.GetLastNaturalStopID();
     }
-    
+
+    lldb::EventSP
+    GetStopEventForStopID (uint32_t stop_id) const
+    {
+        return m_mod_id.GetStopEventForStopID(stop_id);
+    }
+
     //------------------------------------------------------------------
     /// Set accessor for the process exit status (return code).
     ///

Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Wed May 20 05:15:47 2015
@@ -603,6 +603,30 @@ SBProcess::GetStopID(bool include_expres
     return 0;
 }
 
+SBEvent
+SBProcess::GetStopEventForStopID(uint32_t stop_id)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+    SBEvent sb_event;
+    EventSP event_sp;
+    ProcessSP process_sp(GetSP());
+    if (process_sp)
+    {
+        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+        event_sp = process_sp->GetStopEventForStopID(stop_id);
+        sb_event.reset(event_sp);
+    }
+
+    if (log)
+        log->Printf ("SBProcess(%p)::GetStopEventForStopID (stop_id=%" PRIu32 ") => SBEvent(%p)",
+                     static_cast<void*>(process_sp.get()),
+                     stop_id,
+                     static_cast<void*>(event_sp.get()));
+
+    return sb_event;
+}
+
 StateType
 SBProcess::GetState ()
 {

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed May 20 05:15:47 2015
@@ -1796,6 +1796,7 @@ Process::SetPrivateState (StateType new_
     if (state_changed)
     {
         m_private_state.SetValueNoLock (new_state);
+        EventSP event_sp (new Event (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state)));
         if (StateIsStoppedState(new_state, false))
         {
             // Note, this currently assumes that all threads in the list
@@ -1812,15 +1813,18 @@ Process::SetPrivateState (StateType new_
             m_thread_list.DidStop();
 
             m_mod_id.BumpStopID();
+            if (!m_mod_id.IsLastResumeForUserExpression())
+                m_mod_id.SetStopEventForLastNaturalStopID(event_sp);
             m_memory_cache.Clear();
             if (log)
                 log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_mod_id.GetStopID());
         }
+
         // Use our target to get a shared pointer to ourselves...
         if (m_finalize_called && PrivateStateThreadIsValid() == false)
-            BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
+            BroadcastEvent (event_sp);
         else
-            m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
+            m_private_state_broadcaster.BroadcastEvent (event_sp);
     }
     else
     {

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Wed May 20 05:15:47 2015
@@ -2617,7 +2617,6 @@ Target::Launch (ProcessLaunchInfo &launc
     {
         if (synchronous_execution || launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
         {
-            EventSP event_sp;
             ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
             if (!hijack_listener_sp)
             {
@@ -2626,7 +2625,7 @@ Target::Launch (ProcessLaunchInfo &launc
                 m_process_sp->HijackProcessEvents(hijack_listener_sp.get());
             }
 
-            StateType state = m_process_sp->WaitForProcessToStop (NULL, &event_sp, false, hijack_listener_sp.get(), NULL);
+            StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false, hijack_listener_sp.get(), NULL);
             
             if (state == eStateStopped)
             {
@@ -2657,14 +2656,6 @@ Target::Launch (ProcessLaunchInfo &launc
                         error = error2;
                     }
                 }
-                else
-                {
-                    assert(synchronous_execution && launch_info.GetFlags().Test(eLaunchFlagStopAtEntry));
-
-                    // Target was stopped at entry as was intended. Need to notify the listeners about it.
-                    m_process_sp->RestoreProcessEvents();
-                    m_process_sp->HandlePrivateEvent(event_sp);
-                }
             }
             else if (state == eStateExited)
             {

Modified: lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py (original)
+++ lldb/trunk/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py Wed May 20 05:15:47 2015
@@ -143,6 +143,7 @@ class MiStartupOptionsTestCase(lldbmi_te
         # After '-exec-run'
         self.expect("-exec-run")
         self.expect("\^running")
+        self.expect("\*stopped,reason=\"breakpoint-hit\"")
 
         # After '-break-insert main.cpp:BP_return'
         line = line_number('main.cpp', '//BP_return')
@@ -152,6 +153,7 @@ class MiStartupOptionsTestCase(lldbmi_te
         # After '-exec-continue'
         self.expect("-exec-continue")
         self.expect("\^running")
+        self.expect("\*stopped,reason=\"breakpoint-hit\"")
 
         # Test that lldb-mi is ready after execution of --source start_script
         self.expect(self.child_prompt, exactly = True)
@@ -184,6 +186,7 @@ class MiStartupOptionsTestCase(lldbmi_te
         # After '-exec-run'
         self.expect("-exec-run")
         self.expect("\^running")
+        self.expect("\*stopped,reason=\"breakpoint-hit\"")
 
         # After '-break-insert main.cpp:BP_return'
         line = line_number('main.cpp', '//BP_return')
@@ -193,6 +196,7 @@ class MiStartupOptionsTestCase(lldbmi_te
         # After '-exec-continue'
         self.expect("-exec-continue")
         self.expect("\^running")
+        self.expect("\*stopped,reason=\"breakpoint-hit\"")
 
         # After '-data-evaluate-expression a'
         self.expect("-data-evaluate-expression a")
@@ -201,6 +205,7 @@ class MiStartupOptionsTestCase(lldbmi_te
         # After '-gdb-exit'
         self.expect("-gdb-exit")
         self.expect("\^exit")
+        self.expect("\*stopped,reason=\"exited-normally\"")
 
     @lldbmi_test
     @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp Wed May 20 05:15:47 2015
@@ -244,6 +244,51 @@ CMICmnLLDBDebugger::WaitForHandleEvent(v
 }
 
 //++ ------------------------------------------------------------------------------------
+// Details: Check if need to rebroadcast stop event. This function will return true if
+//          debugger is in synchronouse mode. In such case the
+//          CMICmnLLDBDebugger::RebroadcastStopEvent should be called to rebroadcast
+//          a new stop event (if any).
+// Type:    Method.
+// Args:    None.
+// Return:  bool    - True = Need to rebroadcast stop event, false = otherwise.
+// Throws:  None.
+//--
+bool
+CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent(void)
+{
+    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+    if (!rSessionInfo.GetDebugger().GetAsync())
+    {
+        const bool include_expression_stops = false;
+        m_nLastStopId = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetStopID(include_expression_stops);
+        return true;
+    }
+
+    return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Rebroadcast stop event if needed. This function should be called only if the
+//          CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent() returned true.
+// Type:    Method.
+// Args:    None.
+// Return:  None.
+// Throws:  None.
+//--
+void
+CMICmnLLDBDebugger::RebroadcastStopEvent(void)
+{
+    lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+    const bool include_expression_stops = false;
+    const uint32_t nStopId = process.GetStopID(include_expression_stops);
+    if (m_nLastStopId != nStopId)
+    {
+        lldb::SBEvent event = process.GetStopEventForStopID(nStopId);
+        process.GetBroadcaster().BroadcastEvent(event);
+    }
+}
+
+//++ ------------------------------------------------------------------------------------
 // Details: Initialize the LLDB Debugger object.
 // Type:    Method.
 // Args:    None.

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h Wed May 20 05:15:47 2015
@@ -50,6 +50,8 @@ class CMICmnLLDBDebugger : public CMICmn
     lldb::SBDebugger &GetTheDebugger(void);
     lldb::SBListener &GetTheListener(void);
     void WaitForHandleEvent(void);
+    bool CheckIfNeedToRebroadcastStopEvent(void);
+    void RebroadcastStopEvent(void);
 
     // MI Commands can use these functions to listen for events they require
     bool RegisterForEvent(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, const MIuint vEventMask);
@@ -110,4 +112,5 @@ class CMICmnLLDBDebugger : public CMICmn
     MapIdToEventMask_t m_mapIdToEventMask;
     std::mutex m_mutexEventQueue;
     std::condition_variable m_conditionEventQueueEmpty;
+    uint32_t m_nLastStopId;
 };

Modified: lldb/trunk/tools/lldb-mi/MIDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriver.cpp?rev=237781&r1=237780&r2=237781&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriver.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIDriver.cpp Wed May 20 05:15:47 2015
@@ -823,11 +823,15 @@ CMIDriver::GetId(void) const
 bool
 CMIDriver::InterpretCommand(const CMIUtilString &vTextLine)
 {
+    const bool bNeedToRebroadcastStopEvent = m_rLldbDebugger.CheckIfNeedToRebroadcastStopEvent();
     bool bCmdYesValid = false;
     bool bOk = InterpretCommandThisDriver(vTextLine, bCmdYesValid);
     if (bOk && !bCmdYesValid)
         bOk = InterpretCommandFallThruDriver(vTextLine, bCmdYesValid);
 
+    if (bNeedToRebroadcastStopEvent)
+        m_rLldbDebugger.RebroadcastStopEvent();
+
     return bOk;
 }
 





More information about the lldb-commits mailing list