Enhance core dump debugging (#2827)
authorJan Vorlicek <jan.vorlicek@volny.cz>
Mon, 24 Jan 2022 19:14:59 +0000 (20:14 +0100)
committerGitHub <noreply@github.com>
Mon, 24 Jan 2022 19:14:59 +0000 (11:14 -0800)
I've found that when a core dump is taken by the OS without the extra
settings that makes it copy shared libraries binaries into the dump,
SOS doesn't work as it relies on the libcoreclr.so ELF header to be
present.
I have discovered a way to make lldb read that data from the image of
the libcoreclr.so that it has loaded together with the dump.

This change makes it possible to use SOS even for the above mentioned
dump cases. In fact, it allows SOS to read any data that were mapped as
read only from any shared library loaded in the process.

src/SOS/lldbplugin/services.cpp

index fbbf40958f9205d50b86e8eb8c37408c415ad249..37ae00c4ee993169c1131005f6d8782d0aab1527 100644 (file)
@@ -778,6 +778,36 @@ LLDBServices::ReadVirtual(
 
     read = process.ReadMemory(offset, buffer, bufferSize, error);
 
+    if (!error.Success())
+    {
+        lldb::SBTarget target = process.GetTarget();
+        if (!target.IsValid())
+        {
+            goto exit;
+        }
+
+        int numModules = target.GetNumModules();
+        bool found = false;
+        for (int i = 0; !found && i < numModules; i++)
+        {
+            lldb::SBModule module = target.GetModuleAtIndex(i);
+            int numSections = module.GetNumSections();
+            for (int j = 0; j < numSections; j++)
+            {
+                lldb::SBSection section = module.GetSectionAtIndex(j);
+                lldb::addr_t loadAddr = section.GetLoadAddress(target);
+                lldb::addr_t byteSize = section.GetByteSize();
+                if ((loadAddr != LLDB_INVALID_ADDRESS) && (offset >= loadAddr) && (offset < loadAddr + byteSize))
+                {
+                    lldb::SBData sectionData = section.GetSectionData(offset - loadAddr, bufferSize);
+                    read = sectionData.ReadRawData(error, 0, buffer, bufferSize);
+                    found = true;
+                    break;
+                }
+            }
+        }
+    }
+
 exit:
     if (bytesRead)
     {