Use last stopped thread ID instead of ICorDebugThread pointer
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Wed, 12 Jul 2017 19:41:30 +0000 (22:41 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/debugger/main.cpp
src/debug/debugger/valuewalk.cpp
src/debug/debugger/varobj.cpp

index 869016c..6e638ad 100644 (file)
@@ -135,7 +135,7 @@ void NotifyEvalComplete();
 // Varobj
 HRESULT ListVariables(ICorDebugFrame *pFrame, std::string &output);
 HRESULT CreateVar(ICorDebugFrame *pFrame, const std::string &varobjName, const std::string &expression, std::string &output);
-HRESULT ListChildren(const std::string &name, int print_values, ICorDebugFrame *pFrame, std::string &output);
+HRESULT ListChildren(const std::string &name, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output);
 HRESULT DeleteVar(const std::string &varobjName);
 
 // TypePrinter
@@ -398,8 +398,23 @@ HRESULT PrintFrames(ICorDebugThread *pThread, std::string &output)
     return S_OK;
 }
 
-std::mutex g_currentThreadMutex;
-ICorDebugThread *g_currentThread = nullptr;
+static std::mutex g_lastStoppedThreadIdMutex;
+static int g_lastStoppedThreadId = 0;
+
+void SetLastStoppedThread(ICorDebugThread *pThread)
+{
+    DWORD threadId = 0;
+    pThread->GetID(&threadId);
+
+    std::lock_guard<std::mutex> lock(g_lastStoppedThreadIdMutex);
+    g_lastStoppedThreadId = threadId;
+}
+
+int GetLastStoppedThreadId()
+{
+    std::lock_guard<std::mutex> lock(g_lastStoppedThreadIdMutex);
+    return g_lastStoppedThreadId;
+}
 
 class ManagedCallback : public ICorDebugManagedCallback, ICorDebugManagedCallback2
 {
@@ -476,13 +491,9 @@ public:
 
             out_printf("*stopped,reason=\"breakpoint-hit\",thread-id=\"%i\",stopped-threads=\"all\",bkptno=\"%u\",%s\n",
                 (int)threadId, (unsigned int)id, output.c_str());
-            {
-                std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-                if (g_currentThread)
-                    g_currentThread->Release();
-                pThread->AddRef();
-                g_currentThread = pThread;
-            }
+
+            SetLastStoppedThread(pThread);
+
             return S_OK;
         }
 
@@ -501,13 +512,7 @@ public:
             out_printf("*stopped,reason=\"end-stepping-range\",thread-id=\"%i\",stopped-threads=\"all\",%s\n",
                 (int)threadId, output.c_str());
 
-            {
-                std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-                if (g_currentThread)
-                    g_currentThread->Release();
-                pThread->AddRef();
-                g_currentThread = pThread;
-            }
+            SetLastStoppedThread(pThread);
 
             return S_OK;
         }
@@ -526,6 +531,7 @@ public:
 
             DWORD threadId = 0;
             pThread->GetID(&threadId);
+            SetLastStoppedThread(pThread);
 
             if (unhandled)
             {
@@ -537,12 +543,6 @@ public:
 
                 out_printf("*stopped,reason=\"exception-received\",exception-stage=\"%s\",thread-id=\"%i\",stopped-threads=\"all\",%s\n",
                     unhandled ? "unhandled" : "handled", (int)threadId, output.c_str());
-
-                std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-                if (g_currentThread)
-                    g_currentThread->Release();
-                pThread->AddRef();
-                g_currentThread = pThread;
             } else {
                 out_printf("=message,text=\"Exception thrown: '%s' in %s\\n\",send-to=\"output-window\",source=\"target-exception\"\n",
                     "<exceptions.name>", "<short.module.name>");
@@ -1100,10 +1100,12 @@ int main(int argc, char *argv[])
             else if (command == "exec-finish")
                 stepType = STEP_OUT;
 
-            HRESULT hr;
+            ToRelease<ICorDebugThread> pThread;
+            DWORD threadId = GetLastStoppedThreadId();
+            HRESULT hr = pProcess->GetThread(threadId, &pThread);
+            if (SUCCEEDED(hr))
             {
-                std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-                hr = g_currentThread ? RunStep(g_currentThread, stepType) : E_FAIL;
+                hr = RunStep(pThread, stepType);
             }
 
             if (FAILED(hr))
@@ -1127,10 +1129,12 @@ int main(int argc, char *argv[])
         {
             // TODO: Add parsing frame indeces and --thread
             std::string output;
-            HRESULT hr;
+            ToRelease<ICorDebugThread> pThread;
+            DWORD threadId = GetLastStoppedThreadId();
+            HRESULT hr = pProcess->GetThread(threadId, &pThread);
+            if (SUCCEEDED(hr))
             {
-                std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-                hr = g_currentThread ? PrintFrames(g_currentThread, output) : E_FAIL;
+                hr = PrintFrames(pThread, output);
             }
             if (SUCCEEDED(hr))
             {
@@ -1145,12 +1149,13 @@ int main(int argc, char *argv[])
         {
             // TODO: Add parsing arguments --thread, --frame
             std::string output;
-            HRESULT hr;
+            ToRelease<ICorDebugThread> pThread;
+            DWORD threadId = GetLastStoppedThreadId();
+            HRESULT hr = pProcess->GetThread(threadId, &pThread);
+            if (SUCCEEDED(hr))
             {
-                std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-
                 ToRelease<ICorDebugFrame> pFrame;
-                hr = g_currentThread ? g_currentThread->GetActiveFrame(&pFrame) : E_FAIL;
+                hr = pThread->GetActiveFrame(&pFrame);
                 if (SUCCEEDED(hr))
                     hr = ListVariables(pFrame, output);
             }
@@ -1171,12 +1176,13 @@ int main(int argc, char *argv[])
             } else {
                 // TODO: Add parsing arguments --thread, --frame
                 std::string output;
-                HRESULT hr;
+                ToRelease<ICorDebugThread> pThread;
+                DWORD threadId = GetLastStoppedThreadId();
+                HRESULT hr = pProcess->GetThread(threadId, &pThread);
+                if (SUCCEEDED(hr))
                 {
-                    std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-
                     ToRelease<ICorDebugFrame> pFrame;
-                    hr = g_currentThread ? g_currentThread->GetActiveFrame(&pFrame) : E_FAIL;
+                    hr = pThread->GetActiveFrame(&pFrame);
                     if (SUCCEEDED(hr))
                         hr = CreateVar(pFrame, args.at(0), args.at(1), output);
                 }
@@ -1214,14 +1220,15 @@ int main(int argc, char *argv[])
             } else {
                 // TODO: Add parsing arguments --thread, --frame
                 std::string output;
-                HRESULT hr;
+                ToRelease<ICorDebugThread> pThread;
+                DWORD threadId = GetLastStoppedThreadId();
+                HRESULT hr = pProcess->GetThread(threadId, &pThread);
+                if (SUCCEEDED(hr))
                 {
-                    std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-
                     ToRelease<ICorDebugFrame> pFrame;
-                    hr = g_currentThread ? g_currentThread->GetActiveFrame(&pFrame) : E_FAIL;
+                    hr = pThread->GetActiveFrame(&pFrame);
                     if (SUCCEEDED(hr))
-                        hr = ListChildren(args.at(var_index), print_values, pFrame, output);
+                        hr = ListChildren(args.at(var_index), print_values, pThread, pFrame, output);
                 }
                 if (SUCCEEDED(hr))
                 {
index 236f307..de0c211 100644 (file)
@@ -38,12 +38,9 @@ HRESULT DereferenceAndUnboxValue(ICorDebugValue * pValue, ICorDebugValue** ppOut
 typedef std::function<HRESULT(mdMethodDef,ICorDebugModule*,ICorDebugType*,ICorDebugValue*,bool,const std::string&)> WalkMembersCallback;
 typedef std::function<HRESULT(ICorDebugILFrame*,ICorDebugValue*,const std::string&)> WalkStackVarsCallback;
 
-extern std::mutex g_currentThreadMutex;
-extern ICorDebugThread *g_currentThread;
-
-std::mutex g_evalMutex;
-std::condition_variable g_evalCV;
-bool g_evalComplete = false;
+static std::mutex g_evalMutex;
+static std::condition_variable g_evalCV;
+static bool g_evalComplete = false;
 
 void NotifyEvalComplete()
 {
@@ -54,6 +51,7 @@ void NotifyEvalComplete()
 }
 
 HRESULT EvalProperty(
+    ICorDebugThread *pThread,
     mdMethodDef methodDef,
     ICorDebugModule *pModule,
     ICorDebugType *pType,
@@ -66,13 +64,8 @@ HRESULT EvalProperty(
     ToRelease<ICorDebugEval> pEval;
 
     ToRelease<ICorDebugProcess> pProcess;
-    {
-        // g_currentThreadMutex should be locked by caller function
-        //std::lock_guard<std::mutex> lock(g_currentThreadMutex);
-
-        IfFailRet(g_currentThread->GetProcess(&pProcess));
-        IfFailRet(g_currentThread->CreateEval(&pEval));
-    }
+    IfFailRet(pThread->GetProcess(&pProcess));
+    IfFailRet(pThread->CreateEval(&pEval));
 
     ToRelease<ICorDebugFunction> pFunc;
     IfFailRet(pModule->GetFunctionFromToken(methodDef, &pFunc));
index ae14e10..bb8bf46 100644 (file)
@@ -25,6 +25,7 @@ typedef std::function<HRESULT(ICorDebugILFrame*,ICorDebugValue*,const std::strin
 HRESULT WalkMembers(ICorDebugValue *pValue, ICorDebugILFrame *pILFrame, WalkMembersCallback cb);
 HRESULT WalkStackVars(ICorDebugFrame *pFrame, WalkStackVarsCallback cb);
 HRESULT EvalProperty(
+    ICorDebugThread *pThread,
     mdMethodDef methodDef,
     ICorDebugModule *pModule,
     ICorDebugType *pType,
@@ -118,6 +119,7 @@ private:
 
 static HRESULT FetchFieldsAndProperties(ICorDebugValue *pInputValue,
                                         ICorDebugType *pTypeCast,
+                                        ICorDebugThread *pThread,
                                         ICorDebugILFrame *pILFrame,
                                         std::vector<VarObjValue> &members,
                                         bool static_members,
@@ -149,7 +151,7 @@ static HRESULT FetchFieldsAndProperties(ICorDebugValue *pInputValue,
 
         if (mdGetter != mdMethodDefNil)
         {
-            EvalProperty(mdGetter, pModule, pType, pInputValue, is_static, &pResultValue);
+            EvalProperty(pThread, mdGetter, pModule, pType, pInputValue, is_static, &pResultValue);
         }
         else
         {
@@ -241,7 +243,7 @@ static void PrintChildren(std::vector<VarObjValue> &members, int print_values, I
     output = ss.str();
 }
 
-HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugFrame *pFrame, std::string &output)
+HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output)
 {
     HRESULT Status;
 
@@ -254,6 +256,7 @@ HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugFrame *pF
 
     IfFailRet(FetchFieldsAndProperties(objValue.value,
                                        NULL,
+                                       pThread,
                                        pILFrame,
                                        members,
                                        objValue.statics_only,
@@ -272,12 +275,12 @@ HRESULT ListChildren(VarObjValue &objValue, int print_values, ICorDebugFrame *pF
     return S_OK;
 }
 
-HRESULT ListChildren(const std::string &name, int print_values, ICorDebugFrame *pFrame, std::string &output)
+HRESULT ListChildren(const std::string &name, int print_values, ICorDebugThread *pThread, ICorDebugFrame *pFrame, std::string &output)
 {
     auto it = g_vars.find(name);
     if (it == g_vars.end())
         return E_FAIL;
-    return ListChildren(it->second, print_values, pFrame, output);
+    return ListChildren(it->second, print_values, pThread, pFrame, output);
 }
 
 HRESULT ListVariables(ICorDebugFrame *pFrame, std::string &output)