[Lldb-commits] [lldb] Fix saving minidump from lldb-dap (PR #89113)

via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 17 11:17:09 PDT 2024


https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/89113

>From 6cccde22723157260e7c0b19bf8372aae8d1afaa Mon Sep 17 00:00:00 2001
From: jeffreytan81 <jeffreytan at fb.com>
Date: Wed, 6 Mar 2024 12:07:03 -0800
Subject: [PATCH 1/3] Fix strcmp build error on buildbot

---
 lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp b/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp
index b0a4446ba01581..40cb63755ee8a5 100644
--- a/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp
+++ b/lldb/test/API/functionalities/fork/concurrent_vfork/main.cpp
@@ -1,6 +1,7 @@
 #include <assert.h>
 #include <iostream>
 #include <mutex>
+#include <string.h>
 #include <sys/wait.h>
 #include <thread>
 #include <unistd.h>

>From 4453a9cb876fe4ed3c5a3ea57a03a428c5d847fc Mon Sep 17 00:00:00 2001
From: jeffreytan81 <jeffreytan at fb.com>
Date: Wed, 17 Apr 2024 10:59:51 -0700
Subject: [PATCH 2/3] Fix saving minidump from lldb-dap

---
 .../Minidump/MinidumpFileBuilder.cpp          | 20 ++++-
 .../Minidump/ObjectFileMinidump.cpp           | 18 ++++-
 .../API/tools/lldb-dap/save-core/Makefile     |  5 ++
 .../lldb-dap/save-core/TestDAP_save_core.py   | 81 +++++++++++++++++++
 .../API/tools/lldb-dap/save-core/main.cpp     |  8 ++
 5 files changed, 125 insertions(+), 7 deletions(-)
 create mode 100644 lldb/test/API/tools/lldb-dap/save-core/Makefile
 create mode 100644 lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py
 create mode 100644 lldb/test/API/tools/lldb-dap/save-core/main.cpp

diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index 50d1b563f469cf..cefd4cb22b6bae 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -20,6 +20,7 @@
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
 #include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -154,8 +155,16 @@ Status WriteString(const std::string &to_write,
 
 llvm::Expected<uint64_t> getModuleFileSize(Target &target,
                                            const ModuleSP &mod) {
-  SectionSP sect_sp = mod->GetObjectFile()->GetBaseAddress().GetSection();
+  // JIT module has the same vm and file size.
   uint64_t SizeOfImage = 0;
+  if (mod->GetObjectFile()->CalculateType() == ObjectFile::Type::eTypeJIT) {
+    for (const auto &section : *mod->GetObjectFile()->GetSectionList()) {
+      SizeOfImage += section->GetByteSize();
+    }
+    return SizeOfImage;
+  }
+
+  SectionSP sect_sp = mod->GetObjectFile()->GetBaseAddress().GetSection();
 
   if (!sect_sp) {
     return llvm::createStringError(std::errc::operation_not_supported,
@@ -226,8 +235,13 @@ Status MinidumpFileBuilder::AddModuleList(Target &target) {
     std::string module_name = mod->GetSpecificationDescription();
     auto maybe_mod_size = getModuleFileSize(target, mod);
     if (!maybe_mod_size) {
-      error.SetErrorStringWithFormat("Unable to get the size of module %s.",
-                                     module_name.c_str());
+      llvm::Error mod_size_err = maybe_mod_size.takeError();
+      llvm::handleAllErrors(std::move(mod_size_err),
+                            [&](const llvm::ErrorInfoBase &E) {
+                              error.SetErrorStringWithFormat(
+                                  "Unable to get the size of module %s: %s.",
+                                  module_name.c_str(), E.message().c_str());
+                            });
       return error;
     }
 
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
index fe609c7f3d2001..1af5d99f0b1604 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Utility/LLDBLog.h"
 
 #include "llvm/Support/FileSystem.h"
 
@@ -68,26 +69,35 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
 
   Target &target = process_sp->GetTarget();
 
+  Log *log = GetLog(LLDBLog::Object);
   error = builder.AddSystemInfo(target.GetArchitecture().GetTriple());
-  if (error.Fail())
+  if (error.Fail()) {
+    LLDB_LOG(log, "AddSystemInfo failed: %s", error.AsCString());
     return false;
+  }
 
   error = builder.AddModuleList(target);
-  if (error.Fail())
+  if (error.Fail()) {
+    LLDB_LOG(log, "AddModuleList failed: %s", error.AsCString());
     return false;
+  }
 
   builder.AddMiscInfo(process_sp);
 
   error = builder.AddThreadList(process_sp);
-  if (error.Fail())
+  if (error.Fail()) {
+    LLDB_LOG(log, "AddThreadList failed: %s", error.AsCString());
     return false;
+  }
 
   // Add any exceptions but only if there are any in any threads.
   builder.AddExceptions(process_sp);
 
   error = builder.AddMemoryList(process_sp, core_style);
-  if (error.Fail())
+  if (error.Fail()) {
+    LLDB_LOG(log, "AddMemoryList failed: %s", error.AsCString());
     return false;
+  }
 
   if (target.GetArchitecture().GetTriple().getOS() ==
       llvm::Triple::OSType::Linux) {
diff --git a/lldb/test/API/tools/lldb-dap/save-core/Makefile b/lldb/test/API/tools/lldb-dap/save-core/Makefile
new file mode 100644
index 00000000000000..b7f3072e28c9d9
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/save-core/Makefile
@@ -0,0 +1,5 @@
+ENABLE_THREADS := YES
+
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py b/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py
new file mode 100644
index 00000000000000..cff89a98fe72ec
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py
@@ -0,0 +1,81 @@
+"""
+Test saving core minidump from lldb-dap
+"""
+
+
+import dap_server
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbdap_testcase
+
+
+class TestDAP_save_core(lldbdap_testcase.DAPTestCaseBase):
+    @skipUnlessArch("x86_64")
+    @skipUnlessPlatform(["linux"])
+    def test_save_core(self):
+        """
+        Tests saving core minidump from lldb-dap.
+        """
+        program = self.getBuildArtifact("a.out")
+        self.build_and_launch(program)
+        source = "main.cpp"
+        # source_path = os.path.join(os.getcwd(), source)
+        breakpoint1_line = line_number(source, "// breakpoint 1")
+        lines = [breakpoint1_line]
+        # Set breakpoint in the thread function so we can step the threads
+        breakpoint_ids = self.set_source_breakpoints(source, lines)
+        self.assertEqual(
+            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
+        )
+        self.continue_to_breakpoints(breakpoint_ids)
+        
+        # Getting dap stack trace may trigger __lldb_caller_function JIT module to be created.
+        self.get_stackFrames(startFrame=0)
+        
+        # Evaluating an expression that cause "_$__lldb_valid_pointer_check" JIT module to be created.
+        expression = 'printf("this is a test")'
+        self.dap_server.request_evaluate(expression, context="watch")
+        
+        # Verify "_$__lldb_valid_pointer_check" JIT module is created.
+        modules = self.dap_server.get_modules()
+        self.assertTrue(modules["_$__lldb_valid_pointer_check"])
+        thread_count = len(self.dap_server.get_threads())
+        
+        core_stack = self.getBuildArtifact("core.stack.dmp")
+        core_dirty = self.getBuildArtifact("core.dirty.dmp")
+        core_full = self.getBuildArtifact("core.full.dmp")
+        
+        base_command = "`process save-core --plugin-name=minidump "
+        self.dap_server.request_evaluate(base_command + " --style=stack '%s'" % (core_stack), context="repl")
+        
+        self.assertTrue(os.path.isfile(core_stack))
+        self.verify_core_file(
+            core_stack, len(modules), thread_count
+        )
+
+        self.dap_server.request_evaluate(base_command + " --style=modified-memory '%s'" % (core_dirty), context="repl")
+        self.assertTrue(os.path.isfile(core_dirty))
+        self.verify_core_file(
+            core_dirty, len(modules), thread_count
+        )
+
+        self.dap_server.request_evaluate(base_command + " --style=full '%s'" % (core_full), context="repl")
+        self.assertTrue(os.path.isfile(core_full))
+        self.verify_core_file(
+            core_full, len(modules), thread_count
+        )
+
+    def verify_core_file(
+          self, core_path, expected_module_count, expected_thread_count
+      ):
+          # To verify, we'll launch with the mini dump
+          target = self.dbg.CreateTarget(None)
+          process = target.LoadCore(core_path)
+
+          # check if the core is in desired state
+          self.assertTrue(process, PROCESS_IS_VALID)
+          self.assertTrue(process.GetProcessInfo().IsValid())
+          self.assertNotEqual(target.GetTriple().find("linux"), -1)
+          self.assertTrue(target.GetNumModules(), expected_module_count)
+          self.assertEqual(process.GetNumThreads(), expected_thread_count)
diff --git a/lldb/test/API/tools/lldb-dap/save-core/main.cpp b/lldb/test/API/tools/lldb-dap/save-core/main.cpp
new file mode 100644
index 00000000000000..8905beb5e7eff6
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/save-core/main.cpp
@@ -0,0 +1,8 @@
+int function(int x) {
+  if ((x % 2) == 0)
+    return function(x - 1) + x; // breakpoint 1
+  else
+    return x;
+}
+
+int main(int argc, char const *argv[]) { return function(2); }

>From 51ac4671a2ed8e5baabf05be9f75fca19aec36a9 Mon Sep 17 00:00:00 2001
From: jeffreytan81 <jeffreytan at fb.com>
Date: Wed, 17 Apr 2024 11:16:46 -0700
Subject: [PATCH 3/3] Fix formatter

---
 .../lldb-dap/save-core/TestDAP_save_core.py   | 62 +++++++++----------
 1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py b/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py
index cff89a98fe72ec..4045dd8fb6569f 100644
--- a/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py
+++ b/lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py
@@ -2,12 +2,11 @@
 Test saving core minidump from lldb-dap
 """
 
-
 import dap_server
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
 import lldbdap_testcase
+from lldbsuite.test import lldbutil
 
 
 class TestDAP_save_core(lldbdap_testcase.DAPTestCaseBase):
@@ -29,53 +28,52 @@ def test_save_core(self):
             len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
         )
         self.continue_to_breakpoints(breakpoint_ids)
-        
+
         # Getting dap stack trace may trigger __lldb_caller_function JIT module to be created.
         self.get_stackFrames(startFrame=0)
-        
+
         # Evaluating an expression that cause "_$__lldb_valid_pointer_check" JIT module to be created.
         expression = 'printf("this is a test")'
         self.dap_server.request_evaluate(expression, context="watch")
-        
+
         # Verify "_$__lldb_valid_pointer_check" JIT module is created.
         modules = self.dap_server.get_modules()
         self.assertTrue(modules["_$__lldb_valid_pointer_check"])
         thread_count = len(self.dap_server.get_threads())
-        
+
         core_stack = self.getBuildArtifact("core.stack.dmp")
         core_dirty = self.getBuildArtifact("core.dirty.dmp")
         core_full = self.getBuildArtifact("core.full.dmp")
-        
+
         base_command = "`process save-core --plugin-name=minidump "
-        self.dap_server.request_evaluate(base_command + " --style=stack '%s'" % (core_stack), context="repl")
-        
-        self.assertTrue(os.path.isfile(core_stack))
-        self.verify_core_file(
-            core_stack, len(modules), thread_count
+        self.dap_server.request_evaluate(
+            base_command + " --style=stack '%s'" % (core_stack), context="repl"
         )
 
-        self.dap_server.request_evaluate(base_command + " --style=modified-memory '%s'" % (core_dirty), context="repl")
-        self.assertTrue(os.path.isfile(core_dirty))
-        self.verify_core_file(
-            core_dirty, len(modules), thread_count
+        self.assertTrue(os.path.isfile(core_stack))
+        self.verify_core_file(core_stack, len(modules), thread_count)
+
+        self.dap_server.request_evaluate(
+            base_command + " --style=modified-memory '%s'" % (core_dirty),
+            context="repl",
         )
+        self.assertTrue(os.path.isfile(core_dirty))
+        self.verify_core_file(core_dirty, len(modules), thread_count)
 
-        self.dap_server.request_evaluate(base_command + " --style=full '%s'" % (core_full), context="repl")
-        self.assertTrue(os.path.isfile(core_full))
-        self.verify_core_file(
-            core_full, len(modules), thread_count
+        self.dap_server.request_evaluate(
+            base_command + " --style=full '%s'" % (core_full), context="repl"
         )
+        self.assertTrue(os.path.isfile(core_full))
+        self.verify_core_file(core_full, len(modules), thread_count)
 
-    def verify_core_file(
-          self, core_path, expected_module_count, expected_thread_count
-      ):
-          # To verify, we'll launch with the mini dump
-          target = self.dbg.CreateTarget(None)
-          process = target.LoadCore(core_path)
+    def verify_core_file(self, core_path, expected_module_count, expected_thread_count):
+        # To verify, we'll launch with the mini dump
+        target = self.dbg.CreateTarget(None)
+        process = target.LoadCore(core_path)
 
-          # check if the core is in desired state
-          self.assertTrue(process, PROCESS_IS_VALID)
-          self.assertTrue(process.GetProcessInfo().IsValid())
-          self.assertNotEqual(target.GetTriple().find("linux"), -1)
-          self.assertTrue(target.GetNumModules(), expected_module_count)
-          self.assertEqual(process.GetNumThreads(), expected_thread_count)
+        # check if the core is in desired state
+        self.assertTrue(process, PROCESS_IS_VALID)
+        self.assertTrue(process.GetProcessInfo().IsValid())
+        self.assertNotEqual(target.GetTriple().find("linux"), -1)
+        self.assertTrue(target.GetNumModules(), expected_module_count)
+        self.assertEqual(process.GetNumThreads(), expected_thread_count)



More information about the lldb-commits mailing list