[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 §ion : *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