Add resolve routine for source files and code lines.
authorMikhail Kurinnoi <m.kurinnoi@samsung.com>
Mon, 10 Aug 2020 15:24:01 +0000 (18:24 +0300)
committerAlexander Soldatov/Platform Lab /SRR/Staff Engineer/Samsung Electronics <soldatov.a@samsung.com>
Fri, 21 Aug 2020 09:22:15 +0000 (12:22 +0300)
src/debug/netcoredbg/modules.cpp
src/debug/netcoredbg/modules.h

index fa885879532be94c8a48ac2a1159fd6059937c73..0807256b4a01f78b54c3f441ed956c882ebdb877 100644 (file)
@@ -176,7 +176,6 @@ HRESULT Modules::GetLocationInAny(
     ULONG linenum,
     ULONG32 &ilOffset,
     mdMethodDef &methodToken,
-    std::string &fullname,
     ICorDebugModule **ppModule)
 {
     HRESULT Status;
@@ -196,8 +195,6 @@ HRESULT Modules::GetLocationInAny(
         if (FAILED(GetSequencePointByILOffset(mdInfo.symbols.get(), methodToken, ilOffset, &resolvedSequencePoint)))
             continue;
 
-        fullname = resolvedSequencePoint.document;
-
         mdInfo.module->AddRef();
         *ppModule = mdInfo.module.GetPtr();
         return S_OK;
@@ -210,8 +207,7 @@ HRESULT Modules::GetLocationInModule(
     std::string filename,
     ULONG linenum,
     ULONG32 &ilOffset,
-    mdMethodDef &methodToken,
-    std::string &fullname)
+    mdMethodDef &methodToken)
 {
     HRESULT Status;
 
@@ -230,8 +226,6 @@ HRESULT Modules::GetLocationInModule(
     SequencePoint resolvedSequencePoint;
     IfFailRet(GetSequencePointByILOffset(info_pair->second.symbols.get(), methodToken, ilOffset, &resolvedSequencePoint));
 
-    fullname = resolvedSequencePoint.document;
-
     return S_OK;
 }
 
@@ -474,6 +468,9 @@ HRESULT Modules::TryLoadModuleSymbols(
         }
     }
 
+    if (module.symbolStatus == SymbolsLoaded)
+        IfFailRet(Modules::FillSourcesCodeLinesForModule(pMDImport, symbolReader.get()));
+
     IfFailRet(GetModuleId(pModule, module.id));
 
     CORDB_ADDRESS baseAddress;
@@ -580,3 +577,79 @@ HRESULT Modules::ForEachModule(std::function<HRESULT(ICorDebugModule *pModule)>
     }
     return S_OK;
 }
+
+HRESULT Modules::FillSourcesCodeLinesForModule(IMetaDataImport *pMDImport, SymbolReader *symbolReader)
+{
+    HRESULT Status;
+    ULONG numTypedefs = 0;
+    HCORENUM fEnum = NULL;
+    mdTypeDef typeDef;
+    while(SUCCEEDED(pMDImport->EnumTypeDefs(&fEnum, &typeDef, 1, &numTypedefs)) && numTypedefs != 0)
+    {
+        ULONG numMethods = 0;
+        HCORENUM fEnum = NULL;
+        mdMethodDef methodDef;
+        while(SUCCEEDED(pMDImport->EnumMethods(&fEnum, typeDef, &methodDef, 1, &numMethods)) && numMethods != 0)
+        {
+            std::vector<SymbolReader::SequencePoint> points;
+            if (FAILED(symbolReader->GetSequencePoints(methodDef, points)))
+                continue;
+
+            for (auto &point : points)
+            {
+                if (point.startLine == SymbolReader::HiddenLine)
+                    continue;
+
+                std::string fullPath = to_utf8(point.document);
+
+#ifdef WIN32
+                IfFailRet(SymbolReader::StringToUpper(fullPath));
+#endif
+
+                auto &codeLinesFullPath = m_sourcesCodeLines[fullPath];
+                for (int i = point.startLine; i <= point.endLine; i++)
+                    codeLinesFullPath[i] = point.startLine;
+
+                // TODO care about files with same name but with different paths
+                m_sourcesFullPaths[GetFileName(fullPath)] = fullPath;
+            }
+        }
+        pMDImport->CloseEnum(fEnum);
+    }
+    pMDImport->CloseEnum(fEnum);
+
+    return S_OK;
+}
+
+HRESULT Modules::ResolveBreakpointFileAndLine(std::string &filename, int32_t &linenum)
+{
+#ifdef WIN32
+    HRESULT Status;
+    IfFailRet(SymbolReader::StringToUpper(filename));
+#endif
+
+    auto searchByFullPath = m_sourcesCodeLines.find(filename);
+    if (searchByFullPath == m_sourcesCodeLines.end())
+    {
+        // TODO care about files with same name but with different paths, care about files with relative paths
+        auto searchByFileName = m_sourcesFullPaths.find(GetFileName(filename));
+        if (searchByFileName == m_sourcesFullPaths.end())
+            return E_FAIL;
+
+        filename = searchByFileName->second;
+
+        searchByFullPath = m_sourcesCodeLines.find(filename);
+        if (searchByFullPath == m_sourcesCodeLines.end())
+            return E_FAIL;
+    }
+
+    auto &codeLines = searchByFullPath->second;
+
+    auto resolvedLine = codeLines.lower_bound(linenum);
+    if (resolvedLine == codeLines.end())
+        return E_FAIL;
+
+    linenum = resolvedLine->second;
+
+    return S_OK;
+}
index c747196d4efe4a086213a83f256b20d21168a946..230cae39cc614c445bba02c61d68896729133c4d 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <functional>
 #include <unordered_map>
+#include <map>
 #include <mutex>
 #include <memory>
 
@@ -40,6 +41,10 @@ class Modules
         ResolveFunctionBreakpointCallback cb);
     static bool IsTargetFunction(const std::vector<std::string> &fullName, const std::vector<std::string> &targetName);
 
+    std::unordered_map<std::string, std::map<int32_t, int32_t>> m_sourcesCodeLines;
+    std::unordered_map<std::string, std::string> m_sourcesFullPaths;
+    HRESULT Modules::FillSourcesCodeLinesForModule(IMetaDataImport *pMDImport, SymbolReader *symbolReader);
+
 public:
     struct SequencePoint {
         int32_t startLine;
@@ -65,15 +70,13 @@ public:
         std::string filename,
         ULONG linenum,
         ULONG32 &ilOffset,
-        mdMethodDef &methodToken,
-        std::string &fullname);
+        mdMethodDef &methodToken);
 
     HRESULT GetLocationInAny(
         std::string filename,
         ULONG linenum,
         ULONG32 &ilOffset,
         mdMethodDef &methodToken,
-        std::string &fullname,
         ICorDebugModule **ppModule);
 
     HRESULT ResolveFunctionInAny(
@@ -115,4 +118,6 @@ public:
         SequencePoint *sequencePoint);
 
     HRESULT ForEachModule(std::function<HRESULT(ICorDebugModule *pModule)> cb);
+
+    HRESULT ResolveBreakpointFileAndLine(std::string &filename, int32_t &linenum);
 };