[Lldb-commits] [PATCH] D93939: [elf-core] Improve reading memory from core file

Djordje Todorovic via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 30 01:36:02 PST 2020


djtodoro created this revision.
djtodoro added reviewers: labath, JDevlieghere.
djtodoro added a project: LLDB.
Herald added a subscriber: pengfei.
djtodoro requested review of this revision.
Herald added a subscriber: lldb-commits.

This patch tries to improve memory-read from core files (in order to improve disassembly functionality).
I am using RHEL 7.7 (linux kernel 3.10) and for a lot of cases, I was not able to disassemble some functions from backtrace when debugging crashes from core files. It outputs some dummy code as following:

  (lldb) disassemble
  example`fn:
      0x55deb51866b0 <+0>:   addb   %al, (%rax)
      0x55deb51866b2 <+2>:   addb   %al, (%rax)
      0x55deb51866b4 <+4>:   addb   %al, (%rax)
      0x55deb51866b6 <+6>:   addb   %al, (%rax)
      ....

The cause of the problem was the fact we are returning all the zeros from `ProcessElfCore::ReadMemory()` that is being called within `Disassembler::ParseInstructions()` and it disassembles some dummy opcodes from the buffer returned. If we are about to fill the buffer with all zeros, I guess it is safe to just return zero, and to proceed with reading from file itself (using the `ReadMemoryFromFileCache()`) (an alternative is to force/prefer `ReadMemoryFromFileCache()` by settimg `prefer_file_cache` to true before calling `ReadMemory()`).

Before this patch (simple example that has been attached into the test):

  $ lldb lldb/test/API/functionalities/postmortem/elf-core/linux-x86_64-for-disassemble.out -c lldb/test/API/functionalities/postmortem/elf-core/linux-x86_64-for-disassemble.core
  (lldb) f 4
  frame #4: 0x00007f1d2f862545 libc.so.6`__libc_start_main + 245
  libc.so.6`__libc_start_main:
  ->  0x7f1d2f862545 <+245>: addb   %al, (%rax)
      0x7f1d2f862547 <+247>: addb   %al, (%rax)
      0x7f1d2f862549 <+249>: addb   %al, (%rax)
      0x7f1d2f86254b <+251>: addb   %al, (%rax)

After this patch applied:

  (lldb) f 4
  frame #4: 0x00007f1d2f862545 libc.so.6`__libc_start_main + 245
  libc.so.6`__libc_start_main:
  ->  0x7f1d2f862545 <+245>: movl   %eax, %edi
      0x7f1d2f862547 <+247>: callq  0x39d10                   ; exit
      0x7f1d2f86254c <+252>: xorl   %edx, %edx
      0x7f1d2f86254e <+254>: jmp    0x22489                   ; <+57>

GDB was able to disassemble all the functions from core file.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D93939

Files:
  lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
  lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
  lldb/test/API/functionalities/postmortem/elf-core/linux-x86_64-for-disassemble.core
  lldb/test/API/functionalities/postmortem/elf-core/linux-x86_64-for-disassemble.out


Index: lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
===================================================================
--- lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -155,6 +155,37 @@
         self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions,
                      "a.out")
 
+
+    @skipIf(triple='^mips')
+    @skipIfLLVMTargetMissing("X86")
+    @skipIfWindows
+    @skipIfReproducer
+    def test_frame_disassemble(self):
+        """Test that we are able to disassemble all the frames"""
+        disasmtarget = self.dbg.CreateTarget("linux-x86_64-for-disassemble.out")
+        disasmprocess = disasmtarget.LoadCore("linux-x86_64-for-disassemble.core")
+        self.assertTrue(disasmprocess, PROCESS_IS_VALID)
+
+        disasmthread = disasmprocess.GetSelectedThread()
+        framenum = disasmthread.GetNumFrames()
+        for i in range(framenum):
+            frame = disasmthread.GetFrameAtIndex(i)
+            disassembly = frame.Disassemble()
+            self.assertNotEqual(disassembly, "")
+            self.assertNotIn("error", disassembly)
+            # Make sure we don't have some dummy disassembly.
+            # Each function should start with:
+            #   pushq %rbp
+            #   ...
+            # Sometimes it just prints some dummy code as:
+            #   addb %al, (%rax)
+            #   addb %al, (%rax)
+            #   ...
+            pushrbpinstr = disassembly.splitlines()[1]
+            self.assertNotIn("addb %al, (%rax)", pushrbpinstr)
+
+        self.dbg.DeleteTarget(disasmtarget)
+
     @skipIf(triple='^mips')
     @skipIfLLVMTargetMissing("X86")
     def test_FPR_SSE(self):
Index: lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
===================================================================
--- lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -384,6 +384,11 @@
   if (zero_fill_size)
     memset(((char *)buf) + bytes_copied, 0, zero_fill_size);
 
+  // No data found in the core file, so the buffer contains
+  // all zeros.
+  if (zero_fill_size == size)
+    return 0;
+
   return bytes_copied + zero_fill_size;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93939.314086.patch
Type: text/x-patch
Size: 2306 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20201230/17d8e7e2/attachment.bin>


More information about the lldb-commits mailing list