Return SequencePoint when reporting frame location
authorIgor Kulaychuk <i.kulaychuk@samsung.com>
Sat, 22 Jul 2017 18:22:14 +0000 (21:22 +0300)
committerIgor Kulaychuk <i.kulaychuk@samsung.com>
Mon, 13 Nov 2017 19:22:40 +0000 (22:22 +0300)
src/debug/netcoredbg/breakpoints.cpp
src/debug/netcoredbg/frames.cpp
src/debug/netcoredbg/modules.cpp
src/debug/netcoredbg/modules.h

index 52f08ed..dee1b23 100644 (file)
@@ -80,14 +80,16 @@ HRESULT PrintBreakpoint(ULONG32 id, std::string &output)
 HRESULT HitBreakpoint(ICorDebugThread *pThread, ULONG32 &id, ULONG32 &times)
 {
     HRESULT Status;
+
     ULONG32 ilOffset;
+    Modules::SequencePoint sp;
     mdMethodDef methodToken;
-    std::string fullname;
-    ULONG linenum;
 
     ToRelease<ICorDebugFrame> pFrame;
     IfFailRet(pThread->GetActiveFrame(&pFrame));
-    IfFailRet(Modules::GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum));
+    IfFailRet(pFrame->GetFunctionToken(&methodToken));
+
+    IfFailRet(Modules::GetFrameLocation(pFrame, ilOffset, sp));
 
     std::lock_guard<std::mutex> lock(g_breakMutex);
 
@@ -95,10 +97,10 @@ HRESULT HitBreakpoint(ICorDebugThread *pThread, ULONG32 &id, ULONG32 &times)
     {
         Breakpoint &b = it.second;
 
-        if (b.fullname == fullname &&
+        if (b.fullname == sp.document &&
             b.ilOffset == ilOffset &&
             b.methodToken == methodToken &&
-            b.linenum == linenum &&
+            b.linenum == sp.startLine &&
             b.enabled)
         {
             id = b.id;
index 72a4e4e..676f89b 100644 (file)
@@ -70,22 +70,22 @@ HRESULT PrintThreadsState(ICorDebugController *controller, std::string &output)
 HRESULT PrintFrameLocation(ICorDebugFrame *pFrame, std::string &output)
 {
     HRESULT Status;
+
     ULONG32 ilOffset;
-    mdMethodDef methodToken;
-    std::string fullname;
-    ULONG linenum;
+    Modules::SequencePoint sp;
     bool has_source = false;
 
     std::stringstream ss;
 
-    if (SUCCEEDED(Modules::GetFrameLocation(pFrame, ilOffset, methodToken, fullname, linenum)))
+    if (SUCCEEDED(Modules::GetFrameLocation(pFrame, ilOffset, sp)))
     {
-        ss << "line=\"" << linenum << "\","
-           << "fullname=\"" << Debugger::EscapeMIValue(fullname) << "\","
-            <<"file=\"" << GetFileName(fullname) << "\",";
+        ss << "line=\"" << sp.startLine << "\","
+           << "fullname=\"" << Debugger::EscapeMIValue(sp.document) << "\","
+           << "file=\"" << GetFileName(sp.document) << "\",";
         has_source = true;
     }
 
+    mdMethodDef methodToken;
     IfFailRet(pFrame->GetFunctionToken(&methodToken));
 
     ToRelease<ICorDebugFunction> pFunc;
index 586e194..d8d9943 100644 (file)
@@ -120,12 +120,11 @@ HRESULT GetLocationInModule(ICorDebugModule *pModule,
 
 HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
                          ULONG32 &ilOffset,
-                         mdMethodDef &methodToken,
-                         std::string &fullname,
-                         ULONG &linenum)
+                         Modules::SequencePoint &sequencePoint)
 {
     HRESULT Status;
 
+    mdMethodDef methodToken;
     IfFailRet(pFrame->GetFunctionToken(&methodToken));
 
     ToRelease<ICorDebugFunction> pFunc;
@@ -149,6 +148,9 @@ HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
 
     WCHAR name[MAX_LONGPATH];
 
+    std::vector<SymbolReader::SequencePoint> points;
+    ULONG linenum;
+
     {
         std::lock_guard<std::mutex> lock(g_modulesInfoMutex);
         auto info_pair = g_modulesInfo.find(modAddress);
@@ -158,11 +160,36 @@ HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
         }
 
         IfFailRet(info_pair->second.symbols->GetLineByILOffset(methodToken, ilOffset, &linenum, name, _countof(name)));
+        IfFailRet(info_pair->second.symbols->GetSequencePoints(methodToken, points));
     }
 
-    fullname = to_utf8(name);
+    if (points.empty())
+        return E_FAIL;
 
-    return S_OK;
+    // TODO: Merge with similar code in SymbolReader.cs
+
+    SymbolReader::SequencePoint &nearestPoint = points.front();
+
+    for (auto &p : points)
+    {
+        if (p.offset < ilOffset)
+        {
+            nearestPoint = p;
+            continue;
+        }
+        if (p.offset == ilOffset)
+            nearestPoint = p;
+
+        sequencePoint.startLine = nearestPoint.startLine;
+        sequencePoint.endLine = nearestPoint.endLine;
+        sequencePoint.startColumn = nearestPoint.startColumn;
+        sequencePoint.endColumn = nearestPoint.endColumn;
+        sequencePoint.offset = nearestPoint.offset;
+        sequencePoint.document = to_utf8(name);
+        return S_OK;
+    }
+
+    return E_FAIL;
 }
 
 HRESULT GetStepRangeFromCurrentIP(ICorDebugThread *pThread, COR_DEBUG_STEP_RANGE *range)
index a648658..bf0144c 100644 (file)
@@ -1,6 +1,15 @@
 namespace Modules
 {
 
+struct SequencePoint {
+    int32_t startLine;
+    int32_t startColumn;
+    int32_t endLine;
+    int32_t endColumn;
+    int32_t offset;
+    std::string document;
+};
+
 HRESULT GetModuleId(ICorDebugModule *pModule, std::string &id);
 
 HRESULT GetModuleWithName(const std::string &name, ICorDebugModule **ppModule);
@@ -9,9 +18,7 @@ std::string GetModuleFileName(ICorDebugModule *pModule);
 
 HRESULT GetFrameLocation(ICorDebugFrame *pFrame,
                          ULONG32 &ilOffset,
-                         mdMethodDef &methodToken,
-                         std::string &fullname,
-                         ULONG &linenum);
+                         Modules::SequencePoint &sequencePoint);
 
 HRESULT GetLocationInModule(ICorDebugModule *pModule,
                             std::string filename,