Fix a race condition in lldb-mi.
authorHafiz Abid Qadeer <hafiz_abid@mentor.com>
Wed, 4 Feb 2015 09:59:23 +0000 (09:59 +0000)
committerHafiz Abid Qadeer <hafiz_abid@mentor.com>
Wed, 4 Feb 2015 09:59:23 +0000 (09:59 +0000)
lldb-mi has 3 threads.
1. One that waits for user intput.
2. Another waits for 1st thread to get input command.
3. Waits for events from lldb.

2 & 3 needs to be synchronized so that they don't end up
doing things at same time. For example, while "break insert" is
processing, we can get a breakpoint event. Depending on where we
are in "break-insert", it can have different behavior. In some
cases, it can cause breakpoint to be deleted too. I have added a
mutex so that command processing and event processing are done
exclusively and they are not running at the same time.

In longer term, I think thread 2 & 3 should be merged to be only
one thread which can wait on command or events.

Reviewed in http://reviews.llvm.org/D7371.

llvm-svn: 228128

lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
lldb/tools/lldb-mi/MICmnLLDBDebugger.cpp
lldb/tools/lldb-mi/MIDriver.cpp

index be5904a..f4cefef 100644 (file)
@@ -35,6 +35,7 @@
 #include "MICmnLLDBDebugSessionInfoVarObj.h"
 #include "MICmnMIValueTuple.h"
 #include "MIUtilMapIdToVariant.h"
+#include "MIUtilThreadBaseStd.h"
 
 // Declarations:
 class CMICmnLLDBDebugger;
@@ -156,6 +157,7 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
     bool RecordBrkPtInfo(const MIuint vnBrkPtId, const SBrkPtInfo &vrBrkPtInfo);
     bool RecordBrkPtInfoGet(const MIuint vnBrkPtId, SBrkPtInfo &vrwBrkPtInfo) const;
     bool RecordBrkPtInfoDelete(const MIuint vnBrkPtId);
+    CMIUtilThreadMutex& GetSessionMutex() { return m_sessionMutex;}
     lldb::SBDebugger &GetDebugger() const;
     lldb::SBListener &GetListener() const;
     lldb::SBTarget GetTarget() const;
@@ -200,6 +202,7 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
     CMIUtilMapIdToVariant m_mapIdToSessionData; // Hold and retrieve key to value data available across all commands
     VecVarObj_t m_vecVarObj;                    // Vector of session variable objects
     MapBrkPtIdToBrkPtInfo_t m_mapBrkPtIdToBrkPtInfo;
+    CMIUtilThreadMutex m_sessionMutex;
 };
 
 //++ ------------------------------------------------------------------------------------
index 5ac380c..37ddda4 100644 (file)
@@ -664,7 +664,13 @@ CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
 
     bool bHandledEvent = false;
     bool bExitAppEvent = false;
-    const bool bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
+
+    bool bOk = false;
+    {
+        // Lock Mutex before handling events so that we don't disturb a running cmd
+        CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
+        bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
+    }
     if (!bHandledEvent)
     {
         const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT), event.GetBroadcasterClass()));
index 7b19f15..5628e34 100644 (file)
@@ -41,6 +41,7 @@
 #include "MICmdArgValFile.h"
 #include "MICmdArgValString.h"
 #include "MICmnConfig.h"
+#include "MICmnLLDBDebugSessionInfo.h"
 
 // Instantiations:
 #if _DEBUG
@@ -687,7 +688,13 @@ CMIDriver::ReadStdinLineQueue(void)
         }
 
         // Process the command
-        const bool bOk = InterpretCommand(lineText);
+        bool bOk = false;
+        {
+            // Lock Mutex before processing commands so that we don't disturb an event
+            // that is being processed.
+            CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
+            bOk = InterpretCommand(lineText);
+        }
 
         // Draw prompt if desired
         if (bOk && m_rStdin.GetEnablePrompt())