Refactor frames and threads walking into separate file
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Thu, 13 Jul 2017 02:39:32 +0000 (05:39 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/debugger/CMakeLists.txt
src/debug/debugger/frames.cpp [new file with mode: 0644]
src/debug/debugger/main.cpp

index 8c4d641..615c0c5 100644 (file)
@@ -10,7 +10,8 @@ set(coreclrdbg_SRC
     typeprinter.cpp
     valuewalk.cpp
     valueprint.cpp
-    commands.cpp)
+    commands.cpp
+    frames.cpp)
 
 if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
     add_definitions(-D_TARGET_AMD64_=1)
diff --git a/src/debug/debugger/frames.cpp b/src/debug/debugger/frames.cpp
new file mode 100644 (file)
index 0000000..87c6dc5
--- /dev/null
@@ -0,0 +1,251 @@
+#include "common.h"
+
+#include <sstream>
+#include <vector>
+#include <list>
+
+#include "typeprinter.h"
+
+HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
+                         ULONG32 &ilOffset,
+                         mdMethodDef &methodToken,
+                         std::string &fullname,
+                         ULONG &linenum);
+
+HRESULT PrintThread(ICorDebugThread *pThread, std::string &output)
+{
+    HRESULT Status = S_OK;
+
+    std::stringstream ss;
+
+    DWORD threadId = 0;
+    IfFailRet(pThread->GetID(&threadId));
+
+    ToRelease<ICorDebugProcess> pProcess;
+    IfFailRet(pThread->GetProcess(&pProcess));
+    BOOL running = FALSE;
+    IfFailRet(pProcess->IsRunning(&running));
+
+    ss << "{id=\"" << threadId
+       << "\",name=\"<No name>\",state=\""
+       << (running ? "running" : "stopped") << "\"}";
+
+    output = ss.str();
+
+    return S_OK;
+}
+
+HRESULT PrintThreadsState(ICorDebugController *controller, std::string &output)
+{
+    HRESULT Status = S_OK;
+
+    ToRelease<ICorDebugThreadEnum> pThreads;
+    IfFailRet(controller->EnumerateThreads(&pThreads));
+
+    std::stringstream ss;
+
+    ss << "threads=[";
+
+    ICorDebugThread *handle;
+    ULONG fetched;
+    const char *sep = "";
+    while (SUCCEEDED(Status = pThreads->Next(1, &handle, &fetched)) && fetched == 1)
+    {
+        ToRelease<ICorDebugThread> pThread(handle);
+
+        std::string threadOutput;
+        PrintThread(pThread, threadOutput);
+
+        ss << sep << threadOutput;
+        sep = ",";
+    }
+
+    ss << "]";
+    output = ss.str();
+    return S_OK;
+}
+
+HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output)
+{
+    HRESULT Status;
+    ULONG32 ilOffset;
+    mdMethodDef methodToken;
+    std::string fullname;
+    ULONG linenum;
+
+    IfFailRet(GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum));
+
+    std::stringstream ss;
+    ss << "line=\"" << linenum << "\",fullname=\"" << fullname << "\"";
+    output = ss.str();
+
+    return S_OK;
+}
+
+enum FrameType
+{
+    FrameNative,
+    FrameRuntimeUnwindable,
+    FrameILStubOrLCG,
+    FrameUnknown,
+    FrameManaged
+};
+
+typedef std::function<HRESULT(FrameType,ICorDebugFrame*,ICorDebugILFrame*,ICorDebugFunction*)> WalkFramesCallback;
+
+HRESULT WalkFrames(ICorDebugThread *pThread, WalkFramesCallback cb)
+{
+    HRESULT Status;
+
+    ToRelease<ICorDebugThread3> pThread3;
+    ToRelease<ICorDebugStackWalk> pStackWalk;
+
+    IfFailRet(pThread->QueryInterface(IID_ICorDebugThread3, (LPVOID *) &pThread3));
+    IfFailRet(pThread3->CreateStackWalk(&pStackWalk));
+
+    for (Status = S_OK; ; Status = pStackWalk->Next())
+    {
+        if (Status == CORDBG_S_AT_END_OF_STACK)
+            break;
+
+        IfFailRet(Status);
+
+        ToRelease<ICorDebugFrame> pFrame;
+        IfFailRet(pStackWalk->GetFrame(&pFrame));
+        if (Status == S_FALSE)
+        {
+            IfFailRet(cb(FrameNative, pFrame, nullptr, nullptr));
+            continue;
+        }
+
+        ToRelease<ICorDebugRuntimeUnwindableFrame> pRuntimeUnwindableFrame;
+        Status = pFrame->QueryInterface(IID_ICorDebugRuntimeUnwindableFrame, (LPVOID *) &pRuntimeUnwindableFrame);
+        if (SUCCEEDED(Status))
+        {
+            IfFailRet(cb(FrameRuntimeUnwindable, pFrame, nullptr, nullptr));
+            continue;
+        }
+
+        ToRelease<ICorDebugILFrame> pILFrame;
+        HRESULT hrILFrame = pFrame->QueryInterface(IID_ICorDebugILFrame, (LPVOID*) &pILFrame);
+
+        if (FAILED(hrILFrame))
+        {
+            IfFailRet(cb(FrameUnknown, pFrame, nullptr, nullptr));
+            continue;
+        }
+
+        ToRelease<ICorDebugFunction> pFunction;
+        Status = pFrame->GetFunction(&pFunction);
+        if (FAILED(Status))
+        {
+            IfFailRet(cb(FrameILStubOrLCG, pFrame, pILFrame, nullptr));
+            continue;
+        }
+
+        IfFailRet(cb(FrameManaged, pFrame, pILFrame, pFunction));
+    }
+
+    return S_OK;
+}
+
+HRESULT GetFrameAt(ICorDebugThread *pThread, int level, ICorDebugFrame **ppFrame)
+{
+    ToRelease<ICorDebugFrame> result;
+
+    int currentFrame = -1;
+
+    HRESULT Status = WalkFrames(pThread, [&](
+        FrameType frameType,
+        ICorDebugFrame *pFrame,
+        ICorDebugILFrame *pILFrame,
+        ICorDebugFunction *pFunction)
+    {
+        currentFrame++;
+
+        if (currentFrame < level)
+            return S_OK;
+        else if (currentFrame > level)
+            return E_FAIL;
+
+        if (currentFrame == level && frameType == FrameManaged)
+        {
+            pFrame->AddRef();
+            result = pFrame;
+        }
+        return E_FAIL;
+    });
+
+    if (result)
+    {
+        *ppFrame = result.Detach();
+        return S_OK;
+    }
+
+    return Status;
+}
+
+HRESULT PrintFrames(ICorDebugThread *pThread, std::string &output, int lowFrame = 0, int highFrame = INT_MAX)
+{
+    HRESULT Status;
+    std::stringstream ss;
+
+    int currentFrame = -1;
+
+    ss << "stack=[";
+
+    IfFailRet(WalkFrames(pThread, [&](
+        FrameType frameType,
+        ICorDebugFrame *pFrame,
+        ICorDebugILFrame *pILFrame,
+        ICorDebugFunction *pFunction)
+    {
+        currentFrame++;
+
+        if (currentFrame < lowFrame)
+            return S_OK;
+        if (currentFrame > highFrame)
+            return S_OK; // Todo implement fast break mechanism
+
+        ss << (currentFrame != 0 ? "," : "");
+
+        switch(frameType)
+        {
+            case FrameNative:
+                ss << "frame={level=\"" << currentFrame << "\",func=\"[NativeStackFrame]\"}";
+                break;
+            case FrameRuntimeUnwindable:
+                ss << "frame={level=\"" << currentFrame << "\",func=\"[RuntimeUnwindableFrame]\"}";
+                break;
+            case FrameILStubOrLCG:
+                ss << "frame={level=\"" << currentFrame << "\",func=\"[IL Stub or LCG]\"}";
+                break;
+            case FrameUnknown:
+                ss << "frame={level=\"" << currentFrame << "\",func=\"?\"}";
+                break;
+            case FrameManaged:
+                {
+                    std::string frameLocation;
+                    PrintFrameLocation(pFrame, frameLocation);
+
+                    ss << (currentFrame != 0 ? "," : "");
+                    ss << "frame={level=\"" << currentFrame << "\",";
+                    if (!frameLocation.empty())
+                        ss << frameLocation << ",";
+
+                    std::string methodName;
+                    TypePrinter::GetMethodName(pFrame, methodName);
+
+                    ss << "func=\"" << methodName << "\"}";
+                }
+                break;
+        }
+        return S_OK;
+    }));
+
+    ss << "]";
+
+    output = ss.str();
+
+    return S_OK;
+}
index dc36258..60182ec 100644 (file)
@@ -118,87 +118,15 @@ HRESULT TryLoadModuleSymbols(ICorDebugModule *pModule,
                              bool &symbolsLoaded,
                              CORDB_ADDRESS &baseAddress,
                              ULONG32 &size);
-HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
-                         ULONG32 &ilOffset,
-                         mdMethodDef &methodToken,
-                         std::string &fullname,
-                         ULONG &linenum);
+
 
 // Valuewalk
 void NotifyEvalComplete();
 
+// Frames
+HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output);
 
-HRESULT PrintThread(ICorDebugThread *pThread, std::string &output)
-{
-    HRESULT Status = S_OK;
-
-    std::stringstream ss;
-
-    DWORD threadId = 0;
-    IfFailRet(pThread->GetID(&threadId));
-
-    ToRelease<ICorDebugProcess> pProcess;
-    IfFailRet(pThread->GetProcess(&pProcess));
-    BOOL running = FALSE;
-    IfFailRet(pProcess->IsRunning(&running));
-
-    ss << "{id=\"" << threadId
-       << "\",name=\"<No name>\",state=\""
-       << (running ? "running" : "stopped") << "\"}";
-
-    output = ss.str();
-
-    return S_OK;
-}
-
-HRESULT PrintThreadsState(ICorDebugController *controller, std::string &output)
-{
-    HRESULT Status = S_OK;
-
-    ToRelease<ICorDebugThreadEnum> pThreads;
-    IfFailRet(controller->EnumerateThreads(&pThreads));
-
-    std::stringstream ss;
-
-    ss << "threads=[";
-
-    ICorDebugThread *handle;
-    ULONG fetched;
-    const char *sep = "";
-    while (SUCCEEDED(Status = pThreads->Next(1, &handle, &fetched)) && fetched == 1)
-    {
-        ToRelease<ICorDebugThread> pThread(handle);
-
-        std::string threadOutput;
-        PrintThread(pThread, threadOutput);
-
-        ss << sep << threadOutput;
-        sep = ",";
-    }
-
-    ss << "]";
-    output = ss.str();
-    return S_OK;
-}
-
-HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output)
-{
-    HRESULT Status;
-    ULONG32 ilOffset;
-    mdMethodDef methodToken;
-    std::string fullname;
-    ULONG linenum;
-
-    IfFailRet(GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum));
-
-    std::stringstream ss;
-    ss << "line=\"" << linenum << "\",fullname=\"" << fullname << "\"";
-    output = ss.str();
-
-    return S_OK;
-}
-
-HRESULT DisableAllBreakpointsAndSteppersInAppDomain(ICorDebugAppDomain *pAppDomain)
+static HRESULT DisableAllBreakpointsAndSteppersInAppDomain(ICorDebugAppDomain *pAppDomain)
 {
     HRESULT Status;
 
@@ -248,174 +176,6 @@ HRESULT DisableAllBreakpointsAndSteppers(ICorDebugProcess *pProcess)
     return S_OK;
 }
 
-enum FrameType
-{
-    FrameNative,
-    FrameRuntimeUnwindable,
-    FrameILStubOrLCG,
-    FrameUnknown,
-    FrameManaged
-};
-
-typedef std::function<HRESULT(FrameType,ICorDebugFrame*,ICorDebugILFrame*,ICorDebugFunction*)> WalkFramesCallback;
-
-HRESULT WalkFrames(ICorDebugThread *pThread, WalkFramesCallback cb)
-{
-    HRESULT Status;
-
-    ToRelease<ICorDebugThread3> pThread3;
-    ToRelease<ICorDebugStackWalk> pStackWalk;
-
-    IfFailRet(pThread->QueryInterface(IID_ICorDebugThread3, (LPVOID *) &pThread3));
-    IfFailRet(pThread3->CreateStackWalk(&pStackWalk));
-
-    for (Status = S_OK; ; Status = pStackWalk->Next())
-    {
-        if (Status == CORDBG_S_AT_END_OF_STACK)
-            break;
-
-        IfFailRet(Status);
-
-        ToRelease<ICorDebugFrame> pFrame;
-        IfFailRet(pStackWalk->GetFrame(&pFrame));
-        if (Status == S_FALSE)
-        {
-            IfFailRet(cb(FrameNative, pFrame, nullptr, nullptr));
-            continue;
-        }
-
-        ToRelease<ICorDebugRuntimeUnwindableFrame> pRuntimeUnwindableFrame;
-        Status = pFrame->QueryInterface(IID_ICorDebugRuntimeUnwindableFrame, (LPVOID *) &pRuntimeUnwindableFrame);
-        if (SUCCEEDED(Status))
-        {
-            IfFailRet(cb(FrameRuntimeUnwindable, pFrame, nullptr, nullptr));
-            continue;
-        }
-
-        ToRelease<ICorDebugILFrame> pILFrame;
-        HRESULT hrILFrame = pFrame->QueryInterface(IID_ICorDebugILFrame, (LPVOID*) &pILFrame);
-
-        if (FAILED(hrILFrame))
-        {
-            IfFailRet(cb(FrameUnknown, pFrame, nullptr, nullptr));
-            continue;
-        }
-
-        ToRelease<ICorDebugFunction> pFunction;
-        Status = pFrame->GetFunction(&pFunction);
-        if (FAILED(Status))
-        {
-            IfFailRet(cb(FrameILStubOrLCG, pFrame, pILFrame, nullptr));
-            continue;
-        }
-
-        IfFailRet(cb(FrameManaged, pFrame, pILFrame, pFunction));
-    }
-
-    return S_OK;
-}
-
-HRESULT GetFrameAt(ICorDebugThread *pThread, int level, ICorDebugFrame **ppFrame)
-{
-    ToRelease<ICorDebugFrame> result;
-
-    int currentFrame = -1;
-
-    HRESULT Status = WalkFrames(pThread, [&](
-        FrameType frameType,
-        ICorDebugFrame *pFrame,
-        ICorDebugILFrame *pILFrame,
-        ICorDebugFunction *pFunction)
-    {
-        currentFrame++;
-
-        if (currentFrame < level)
-            return S_OK;
-        else if (currentFrame > level)
-            return E_FAIL;
-
-        if (currentFrame == level && frameType == FrameManaged)
-        {
-            pFrame->AddRef();
-            result = pFrame;
-        }
-        return E_FAIL;
-    });
-
-    if (result)
-    {
-        *ppFrame = result.Detach();
-        return S_OK;
-    }
-
-    return Status;
-}
-
-HRESULT PrintFrames(ICorDebugThread *pThread, std::string &output, int lowFrame = 0, int highFrame = INT_MAX)
-{
-    HRESULT Status;
-    std::stringstream ss;
-
-    int currentFrame = -1;
-
-    ss << "stack=[";
-
-    IfFailRet(WalkFrames(pThread, [&](
-        FrameType frameType,
-        ICorDebugFrame *pFrame,
-        ICorDebugILFrame *pILFrame,
-        ICorDebugFunction *pFunction)
-    {
-        currentFrame++;
-
-        if (currentFrame < lowFrame)
-            return S_OK;
-        if (currentFrame > highFrame)
-            return S_OK; // Todo implement fast break mechanism
-
-        ss << (currentFrame != 0 ? "," : "");
-
-        switch(frameType)
-        {
-            case FrameNative:
-                ss << "frame={level=\"" << currentFrame << "\",func=\"[NativeStackFrame]\"}";
-                break;
-            case FrameRuntimeUnwindable:
-                ss << "frame={level=\"" << currentFrame << "\",func=\"[RuntimeUnwindableFrame]\"}";
-                break;
-            case FrameILStubOrLCG:
-                ss << "frame={level=\"" << currentFrame << "\",func=\"[IL Stub or LCG]\"}";
-                break;
-            case FrameUnknown:
-                ss << "frame={level=\"" << currentFrame << "\",func=\"?\"}";
-                break;
-            case FrameManaged:
-                {
-                    std::string frameLocation;
-                    PrintFrameLocation(pFrame, frameLocation);
-
-                    ss << (currentFrame != 0 ? "," : "");
-                    ss << "frame={level=\"" << currentFrame << "\",";
-                    if (!frameLocation.empty())
-                        ss << frameLocation << ",";
-
-                    std::string methodName;
-                    TypePrinter::GetMethodName(pFrame, methodName);
-
-                    ss << "func=\"" << methodName << "\"}";
-                }
-                break;
-        }
-        return S_OK;
-    }));
-
-    ss << "]";
-
-    output = ss.str();
-
-    return S_OK;
-}
-
 static std::mutex g_lastStoppedThreadIdMutex;
 static int g_lastStoppedThreadId = 0;