[Lldb-commits] [lldb] [lldb][Darwin] Remove libsanitizers ASan integration (PR #217791)
Julian Lettner via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 20 16:49:31 PDT 2026
https://github.com/yln updated https://github.com/llvm/llvm-project/pull/217791
>From d301c12b4b2c388ad7604dfceabf0b2341ddebe9 Mon Sep 17 00:00:00 2001
From: Julian Lettner <jlettner at apple.com>
Date: Wed, 5 Aug 2026 16:02:53 -0700
Subject: [PATCH 1/2] [lldb][Darwin] Remove libsanitizers ASan integration
The OS-provided ASan runtime (in libsanitizers)
was removed on Darwin, so remove LLDB's support
for it.
rdar://177086333
---
lldb/include/lldb/lldb-enumerations.h | 2 +-
.../ASanLibsanitizers/CMakeLists.txt | 10 --
...nstrumentationRuntimeASanLibsanitizers.cpp | 119 ------------------
.../InstrumentationRuntimeASanLibsanitizers.h | 52 --------
.../InstrumentationRuntime/CMakeLists.txt | 1 -
lldb/test/API/functionalities/asan/Makefile | 3 -
.../functionalities/asan/TestMemoryHistory.py | 65 ----------
.../functionalities/asan/TestReportData.py | 17 +--
8 files changed, 3 insertions(+), 266 deletions(-)
delete mode 100644 lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/CMakeLists.txt
delete mode 100644 lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp
delete mode 100644 lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index ff80a9df22c5e..aedcfc051a565 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -661,7 +661,7 @@ enum InstrumentationRuntimeType {
eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer = 0x0002,
eInstrumentationRuntimeTypeMainThreadChecker = 0x0003,
eInstrumentationRuntimeTypeSwiftRuntimeReporting = 0x0004,
- eInstrumentationRuntimeTypeLibsanitizersAsan = 0x0005,
+ eInstrumentationRuntimeTypeUnused = 0x0005,
eInstrumentationRuntimeTypeBoundsSafety = 0x0006,
eNumInstrumentationRuntimeTypes
};
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/CMakeLists.txt b/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/CMakeLists.txt
deleted file mode 100644
index 382e38e52ae19..0000000000000
--- a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginInstrumentationRuntimeASanLibsanitizers PLUGIN
- InstrumentationRuntimeASanLibsanitizers.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbSymbol
- lldbTarget
- lldbPluginInstrumentationRuntimeUtility
- )
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp b/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp
deleted file mode 100644
index b1151febb7cc4..0000000000000
--- a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//===-- InstrumentationRuntimeASanLibsanitizers.cpp -----------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "InstrumentationRuntimeASanLibsanitizers.h"
-
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginInterface.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/RegularExpression.h"
-
-#include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASanLibsanitizers)
-
-lldb::InstrumentationRuntimeSP
-InstrumentationRuntimeASanLibsanitizers::CreateInstance(
- const lldb::ProcessSP &process_sp) {
- return InstrumentationRuntimeSP(
- new InstrumentationRuntimeASanLibsanitizers(process_sp));
-}
-
-void InstrumentationRuntimeASanLibsanitizers::Initialize() {
- PluginManager::RegisterPlugin(
- GetPluginNameStatic(),
- "AddressSanitizer instrumentation runtime plugin for Libsanitizers.",
- CreateInstance, GetTypeStatic);
-}
-
-void InstrumentationRuntimeASanLibsanitizers::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb::InstrumentationRuntimeType
-InstrumentationRuntimeASanLibsanitizers::GetTypeStatic() {
- return eInstrumentationRuntimeTypeLibsanitizersAsan;
-}
-
-InstrumentationRuntimeASanLibsanitizers::
- ~InstrumentationRuntimeASanLibsanitizers() {
- Deactivate();
-}
-
-const RegularExpression &
-InstrumentationRuntimeASanLibsanitizers::GetPatternForRuntimeLibrary() {
- static RegularExpression regex(
- llvm::StringRef("libsystem_sanitizers\\.dylib"));
- return regex;
-}
-
-bool InstrumentationRuntimeASanLibsanitizers::CheckIfRuntimeIsValid(
- const lldb::ModuleSP module_sp) {
- const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
- ConstString("__asan_abi_init"), lldb::eSymbolTypeAny);
-
- return symbol != nullptr;
-}
-
-bool InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit(
- void *baton, StoppointCallbackContext *context, user_id_t break_id,
- user_id_t break_loc_id) {
- assert(baton && "null baton");
- if (!baton)
- return false;
-
- InstrumentationRuntimeASanLibsanitizers *const instance =
- static_cast<InstrumentationRuntimeASanLibsanitizers *>(baton);
-
- ProcessSP process_sp = instance->GetProcessSP();
-
- return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id,
- break_loc_id);
-}
-
-void InstrumentationRuntimeASanLibsanitizers::Activate() {
- if (IsActive())
- return;
-
- ProcessSP process_sp = GetProcessSP();
- if (!process_sp)
- return;
-
- Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint(
- GetRuntimeModuleSP(), process_sp,
- ConstString("sanitizers_address_on_report"));
- if (!breakpoint)
- return;
-
- const bool sync = false;
-
- breakpoint->SetCallback(
- InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit, this, sync);
- breakpoint->SetBreakpointKind("address-sanitizer-report");
- SetBreakpointID(breakpoint->GetID());
-
- SetActive(true);
-}
-
-void InstrumentationRuntimeASanLibsanitizers::Deactivate() {
- SetActive(false);
-
- if (GetBreakpointID() == LLDB_INVALID_BREAK_ID)
- return;
-
- if (ProcessSP process_sp = GetProcessSP()) {
- process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
- SetBreakpointID(LLDB_INVALID_BREAK_ID);
- }
-}
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h b/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h
deleted file mode 100644
index abb445a9dd676..0000000000000
--- a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- InstrumentationRuntimeASanLibsanitizers.h ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASANLIBSANITIZERS_INSTRUMENTATIONRUNTIMEASANLIBSANITIZERS_H
-#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASANLIBSANITIZERS_INSTRUMENTATIONRUNTIMEASANLIBSANITIZERS_H
-
-#include "lldb/Target/InstrumentationRuntime.h"
-
-class InstrumentationRuntimeASanLibsanitizers
- : public lldb_private::InstrumentationRuntime {
-public:
- ~InstrumentationRuntimeASanLibsanitizers() override;
-
- static lldb::InstrumentationRuntimeSP
- CreateInstance(const lldb::ProcessSP &process_sp);
-
- static void Initialize();
-
- static void Terminate();
-
- static llvm::StringRef GetPluginNameStatic() { return "Libsanitizers-ASan"; }
-
- static lldb::InstrumentationRuntimeType GetTypeStatic();
-
- llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
-
- virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); }
-
-private:
- InstrumentationRuntimeASanLibsanitizers(const lldb::ProcessSP &process_sp)
- : lldb_private::InstrumentationRuntime(process_sp) {}
-
- const lldb_private::RegularExpression &GetPatternForRuntimeLibrary() override;
-
- bool CheckIfRuntimeIsValid(const lldb::ModuleSP module_sp) override;
-
- void Activate() override;
-
- void Deactivate();
-
- static bool
- NotifyBreakpointHit(void *baton,
- lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
-};
-
-#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASANLIBSANITIZERS_INSTRUMENTATIONRUNTIMEASANLIBSANITIZERS_H
diff --git a/lldb/source/Plugins/InstrumentationRuntime/CMakeLists.txt b/lldb/source/Plugins/InstrumentationRuntime/CMakeLists.txt
index b7e1a602f208f..1c47ba82a0caf 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/CMakeLists.txt
+++ b/lldb/source/Plugins/InstrumentationRuntime/CMakeLists.txt
@@ -1,7 +1,6 @@
set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND InstrumentationRuntime)
add_subdirectory(ASan)
-add_subdirectory(ASanLibsanitizers)
add_subdirectory(BoundsSafety)
add_subdirectory(MainThreadChecker)
add_subdirectory(TSan)
diff --git a/lldb/test/API/functionalities/asan/Makefile b/lldb/test/API/functionalities/asan/Makefile
index eae5ca3e4626c..36d0624216b86 100644
--- a/lldb/test/API/functionalities/asan/Makefile
+++ b/lldb/test/API/functionalities/asan/Makefile
@@ -2,9 +2,6 @@ C_SOURCES := main.c
compiler_rt-asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
compiler_rt-asan: all
-libsanitizers-asan: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
-libsanitizers-asan: all
-
libsanitizers-traces: CFLAGS_EXTRAS := -g -gcolumn-info
libsanitizers-traces: all
diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index b0bdc6e89c28d..eaf4e43ff3bc6 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -7,7 +7,6 @@
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbplatform
from lldbsuite.test import lldbutil
-from lldbsuite.test_event.build_exception import BuildError
class MemoryHistoryTestCase(TestBase):
@@ -20,15 +19,6 @@ def test_compiler_rt_asan(self):
self.build(make_targets=["compiler_rt-asan"])
self.compiler_rt_asan_tests()
- @requireDarwin
- @skipIf(bugnumber="rdar://109913184&143590169")
- def test_libsanitizers_asan(self):
- try:
- self.build(make_targets=["libsanitizers-asan"])
- except BuildError as e:
- self.skipTest("failed to build with libsanitizers")
- self.libsanitizers_asan_tests()
-
@requireDarwin
@skipIf(macos_version=["<", "15.5"])
def test_libsanitizers_traces(self):
@@ -78,61 +68,6 @@ def libsanitizers_traces_tests(self):
self.run_to_breakpoint(target)
self.check_traces()
- def libsanitizers_asan_tests(self):
- target = self.createTestTarget()
-
- self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
-
- self.run_to_breakpoint(target)
- self.check_traces()
-
- self.runCmd("continue")
-
- # Stop on report
- self.expect(
- "thread list",
- "Process should be stopped due to ASan report",
- substrs=["stopped", "stop reason = Use of deallocated memory"],
- )
- self.check_traces()
-
- if self.platformIsDarwin():
- # Make sure we're not stopped in the sanitizer library but instead at the
- # point of failure in the user-code.
- self.assertEqual(self.frame().GetFunctionName(), "main")
-
- # do the same using SB API
- process = self.dbg.GetSelectedTarget().process
- val = (
- process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer")
- )
- addr = val.GetValueAsUnsigned()
- threads = process.GetHistoryThreads(addr)
- self.assertEqual(threads.GetSize(), 2)
-
- history_thread = threads.GetThreadAtIndex(0)
- self.assertTrue(history_thread.num_frames >= 2)
- self.assertEqual(
- history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
- "main.c",
- )
-
- history_thread = threads.GetThreadAtIndex(1)
- self.assertTrue(history_thread.num_frames >= 2)
- self.assertEqual(
- history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
- "main.c",
- )
-
- # let's free the container (SBThreadCollection) and see if the
- # SBThreads still live
- threads = None
- self.assertTrue(history_thread.num_frames >= 2)
- self.assertEqual(
- history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
- "main.c",
- )
-
def compiler_rt_asan_tests(self):
target = self.createTestTarget()
diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py
index aa6e1664ec996..280aa613eb4ad 100644
--- a/lldb/test/API/functionalities/asan/TestReportData.py
+++ b/lldb/test/API/functionalities/asan/TestReportData.py
@@ -7,7 +7,6 @@
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
-from lldbsuite.test_event.build_exception import BuildError
class AsanTestReportDataCase(TestBase):
@@ -21,15 +20,6 @@ def test(self):
self.build(make_targets=["compiler_rt-asan"])
self.asan_tests()
- @requireDarwin
- @skipIf(bugnumber="rdar://109913184&143590169")
- def test_libsanitizers_asan(self):
- try:
- self.build(make_targets=["libsanitizers-asan"])
- except BuildError as e:
- self.skipTest("failed to build with libsanitizers")
- self.asan_tests(libsanitizers=True)
-
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -40,13 +30,10 @@ def setUp(self):
self.line_crash = line_number("main.c", "// BOOM line")
self.col_crash = 16
- def asan_tests(self, libsanitizers=False):
+ def asan_tests(self):
target = self.createTestTarget()
- if libsanitizers:
- self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
- else:
- self.registerSanitizerLibrariesWithTarget(target)
+ self.registerSanitizerLibrariesWithTarget(target)
self.runCmd("run")
>From c5d856900a2928063f3b9e699525a65adb543689 Mon Sep 17 00:00:00 2001
From: Julian Lettner <jlettner at apple.com>
Date: Thu, 20 Aug 2026 16:34:54 -0700
Subject: [PATCH 2/2] [lldb] Fold ReportRetriever back into the ASan plugin
ReportRetriever was factored out of InstrumentationRuntimeASan by
77edd9b77317 (#69388) so the compiler-rt and libsanitizers ASan plugins
could share it. The libsanitizers plugin is gone, leaving
InstrumentationRuntimeASan as the only caller, so fold ReportRetriever
back into InstrumentationRuntimeASan plugin.
---
lldb/include/lldb/lldb-enumerations.h | 2 +-
.../ASan/CMakeLists.txt | 2 +
.../ASan/InstrumentationRuntimeASan.cpp | 235 +++++++++++++++-
.../ASan/InstrumentationRuntimeASan.h | 3 +
.../Utility/CMakeLists.txt | 5 -
.../Utility/ReportRetriever.cpp | 256 ------------------
.../Utility/ReportRetriever.h | 34 ---
.../Utility/Utility.cpp | 2 +-
.../Handler/ExceptionInfoRequestHandler.cpp | 2 +-
9 files changed, 238 insertions(+), 303 deletions(-)
delete mode 100644 lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
delete mode 100644 lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index aedcfc051a565..559d5fbce483c 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -661,7 +661,7 @@ enum InstrumentationRuntimeType {
eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer = 0x0002,
eInstrumentationRuntimeTypeMainThreadChecker = 0x0003,
eInstrumentationRuntimeTypeSwiftRuntimeReporting = 0x0004,
- eInstrumentationRuntimeTypeUnused = 0x0005,
+ eInstrumentationRuntimeTypeUnused = 0x0005, // Free to reuse
eInstrumentationRuntimeTypeBoundsSafety = 0x0006,
eNumInstrumentationRuntimeTypes
};
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt b/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt
index b746a16b31f77..6c793543b1c15 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt
+++ b/lldb/source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt
@@ -4,7 +4,9 @@ add_lldb_library(lldbPluginInstrumentationRuntimeASan PLUGIN
LINK_LIBS
lldbBreakpoint
lldbCore
+ lldbExpression
lldbSymbol
lldbTarget
+ lldbValueObject
lldbPluginInstrumentationRuntimeUtility
)
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
index a09c89103b0e3..af30715294bd6 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp
@@ -9,14 +9,23 @@
#include "InstrumentationRuntimeASan.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/RegularExpression.h"
+#include "lldb/ValueObject/ValueObject.h"
-#include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h"
+#include "Plugins/InstrumentationRuntime/Utility/Utility.h"
+
+#include "llvm/ADT/StringSwitch.h"
using namespace lldb;
using namespace lldb_private;
@@ -60,6 +69,181 @@ bool InstrumentationRuntimeASan::CheckIfRuntimeIsValid(
return symbol != nullptr;
}
+static const char *address_sanitizer_retrieve_report_data_prefix = R"(
+extern "C"
+{
+int __asan_report_present();
+void *__asan_get_report_pc();
+void *__asan_get_report_bp();
+void *__asan_get_report_sp();
+void *__asan_get_report_address();
+const char *__asan_get_report_description();
+int __asan_get_report_access_type();
+size_t __asan_get_report_access_size();
+}
+)";
+
+static const char *address_sanitizer_retrieve_report_data_command = R"(
+struct {
+ int present;
+ int access_type;
+ void *pc;
+ void *bp;
+ void *sp;
+ void *address;
+ size_t access_size;
+ const char *description;
+} t;
+
+t.present = __asan_report_present();
+t.access_type = __asan_get_report_access_type();
+t.pc = __asan_get_report_pc();
+t.bp = __asan_get_report_bp();
+t.sp = __asan_get_report_sp();
+t.address = __asan_get_report_address();
+t.access_size = __asan_get_report_access_size();
+t.description = __asan_get_report_description();
+t
+)";
+
+StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData() {
+ ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return StructuredData::ObjectSP();
+
+ ThreadSP thread_sp =
+ process_sp->GetThreadList().GetExpressionExecutionThread();
+
+ if (!thread_sp)
+ return StructuredData::ObjectSP();
+
+ StackFrameSP frame_sp =
+ thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
+
+ if (!frame_sp)
+ return StructuredData::ObjectSP();
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetTryAllThreads(true);
+ options.SetStopOthers(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTimeout(process_sp->GetUtilityExpressionTimeout());
+ options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
+ options.SetAutoApplyFixIts(false);
+ options.SetLanguage(eLanguageTypeC);
+
+ if (auto [m, _] = GetPreferredAsanModule(process_sp->GetTarget()); m) {
+ SymbolContextList sc_list;
+ sc_list.Append(SymbolContext(std::move(m)));
+ options.SetPreferredSymbolContexts(std::move(sc_list));
+ }
+
+ ValueObjectSP return_value_sp;
+ ExecutionContext exe_ctx;
+ frame_sp->CalculateExecutionContext(exe_ctx);
+ ExpressionResults result = UserExpression::Evaluate(
+ exe_ctx, options, address_sanitizer_retrieve_report_data_command, "",
+ return_value_sp);
+ if (result != eExpressionCompleted) {
+ StreamString ss;
+ ss << "cannot evaluate AddressSanitizer expression:\n";
+ if (return_value_sp)
+ ss << return_value_sp->GetError().AsCString();
+ Debugger::ReportWarning(ss.GetString().str(),
+ process_sp->GetTarget().GetDebugger().GetID());
+ return StructuredData::ObjectSP();
+ }
+
+ int present = return_value_sp->GetValueForExpressionPath(".present")
+ ->GetValueAsUnsigned(0);
+ if (present != 1)
+ return StructuredData::ObjectSP();
+
+ addr_t pc =
+ return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0);
+ addr_t bp =
+ return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0);
+ addr_t sp =
+ return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0);
+ addr_t address = return_value_sp->GetValueForExpressionPath(".address")
+ ->GetValueAsUnsigned(0);
+ addr_t access_type =
+ return_value_sp->GetValueForExpressionPath(".access_type")
+ ->GetValueAsUnsigned(0);
+ addr_t access_size =
+ return_value_sp->GetValueForExpressionPath(".access_size")
+ ->GetValueAsUnsigned(0);
+ addr_t description_ptr =
+ return_value_sp->GetValueForExpressionPath(".description")
+ ->GetValueAsUnsigned(0);
+ std::string description;
+ Status error;
+ process_sp->ReadCStringFromMemory(description_ptr, description, error);
+
+ auto dict = std::make_shared<StructuredData::Dictionary>();
+ if (!dict)
+ return StructuredData::ObjectSP();
+
+ dict->AddStringItem("instrumentation_class", "AddressSanitizer");
+ dict->AddStringItem("stop_type", "fatal_error");
+ dict->AddIntegerItem("pc", pc);
+ dict->AddIntegerItem("bp", bp);
+ dict->AddIntegerItem("sp", sp);
+ dict->AddIntegerItem("address", address);
+ dict->AddIntegerItem("access_type", access_type);
+ dict->AddIntegerItem("access_size", access_size);
+ dict->AddStringItem("description", description);
+
+ return StructuredData::ObjectSP(dict);
+}
+
+static std::string FormatDescription(StructuredData::ObjectSP report) {
+ std::string description = std::string(report->GetAsDictionary()
+ ->GetValueForKey("description")
+ ->GetAsString()
+ ->GetValue());
+ return llvm::StringSwitch<std::string>(description)
+ .Case("heap-use-after-free", "Use of deallocated memory")
+ .Case("heap-buffer-overflow", "Heap buffer overflow")
+ .Case("stack-buffer-underflow", "Stack buffer underflow")
+ .Case("initialization-order-fiasco", "Initialization order problem")
+ .Case("stack-buffer-overflow", "Stack buffer overflow")
+ .Case("stack-use-after-return", "Use of stack memory after return")
+ .Case("use-after-poison", "Use of poisoned memory")
+ .Case("container-overflow", "Container overflow")
+ .Case("stack-use-after-scope", "Use of out-of-scope stack memory")
+ .Case("global-buffer-overflow", "Global buffer overflow")
+ .Case("unknown-crash", "Invalid memory access")
+ .Case("stack-overflow", "Stack space exhausted")
+ .Case("null-deref", "Dereference of null pointer")
+ .Case("wild-jump", "Jump to non-executable address")
+ .Case("wild-addr-write", "Write through wild pointer")
+ .Case("wild-addr-read", "Read from wild pointer")
+ .Case("wild-addr", "Access through wild pointer")
+ .Case("signal", "Deadly signal")
+ .Case("double-free", "Deallocation of freed memory")
+ .Case("new-delete-type-mismatch",
+ "Deallocation size different from allocation size")
+ .Case("bad-free", "Deallocation of non-allocated memory")
+ .Case("alloc-dealloc-mismatch",
+ "Mismatch between allocation and deallocation APIs")
+ .Case("bad-malloc_usable_size", "Invalid argument to malloc_usable_size")
+ .Case("bad-__sanitizer_get_allocated_size",
+ "Invalid argument to __sanitizer_get_allocated_size")
+ .Case("param-overlap",
+ "Call to function disallowing overlapping memory ranges")
+ .Case("negative-size-param", "Negative size used when accessing memory")
+ .Case("bad-__sanitizer_annotate_contiguous_container",
+ "Invalid argument to __sanitizer_annotate_contiguous_container")
+ .Case("odr-violation", "Symbol defined in multiple translation units")
+ .Case(
+ "invalid-pointer-pair",
+ "Comparison or arithmetic on pointers from different memory regions")
+ // for unknown report codes just show the code
+ .Default("AddressSanitizer detected: " + description);
+}
+
bool InstrumentationRuntimeASan::NotifyBreakpointHit(
void *baton, StoppointCallbackContext *context, user_id_t break_id,
user_id_t break_loc_id) {
@@ -72,8 +256,34 @@ bool InstrumentationRuntimeASan::NotifyBreakpointHit(
ProcessSP process_sp = instance->GetProcessSP();
- return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id,
- break_loc_id);
+ // Make sure this is the right process
+ if (!process_sp || process_sp != context->exe_ctx_ref.GetProcessSP())
+ return false;
+
+ if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+ return false;
+
+ StructuredData::ObjectSP report = instance->RetrieveReportData();
+ if (!report || report->GetType() != lldb::eStructuredDataTypeDictionary) {
+ LLDB_LOGF(GetLog(LLDBLog::InstrumentationRuntime),
+ "InstrumentationRuntimeASan::RetrieveReportData() failed");
+ return false;
+ }
+
+ std::string description = FormatDescription(report);
+
+ if (ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP())
+ thread_sp->SetStopInfo(
+ InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(
+ *thread_sp, description, report));
+
+ if (StreamSP stream_sp =
+ process_sp->GetTarget().GetDebugger().GetAsyncOutputStream())
+ stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread "
+ "info -s' to get extended information about the "
+ "report.\n");
+
+ return true; // Return true to stop the target
}
void InstrumentationRuntimeASan::Activate() {
@@ -84,9 +294,24 @@ void InstrumentationRuntimeASan::Activate() {
if (!process_sp)
return;
- Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint(
- GetRuntimeModuleSP(), process_sp, ConstString("_ZN6__asanL7AsanDieEv"));
+ ModuleSP module_sp = GetRuntimeModuleSP();
+ if (!module_sp)
+ return;
+
+ const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
+ ConstString("_ZN6__asanL7AsanDieEv"), eSymbolTypeCode);
+ if (!symbol)
+ return;
+
+ if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
+ return;
+ const bool internal = true;
+ const bool hardware = false;
+ Breakpoint *breakpoint =
+ process_sp->GetTarget()
+ .CreateBreakpoint(symbol->GetAddressRef(), internal, hardware)
+ .get();
if (!breakpoint)
return;
diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
index 177959d7126be..808c5b1baba70 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
+++ b/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h
@@ -10,6 +10,7 @@
#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_ASAN_INSTRUMENTATIONRUNTIMEASAN_H
#include "lldb/Target/InstrumentationRuntime.h"
+#include "lldb/Utility/StructuredData.h"
namespace lldb_private {
@@ -48,6 +49,8 @@ class InstrumentationRuntimeASan : public lldb_private::InstrumentationRuntime {
StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
+
+ StructuredData::ObjectSP RetrieveReportData();
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt b/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt
index 705fe1503fae2..c39e8f17b1f6c 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt
+++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/CMakeLists.txt
@@ -1,12 +1,7 @@
add_lldb_library(lldbPluginInstrumentationRuntimeUtility
- ReportRetriever.cpp
Utility.cpp
LINK_LIBS
- lldbBreakpoint
lldbCore
- lldbExpression
- lldbSymbol
lldbTarget
- lldbValueObject
)
diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
deleted file mode 100644
index 85852ba40c61c..0000000000000
--- a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-//===-- ReportRetriever.cpp -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "ReportRetriever.h"
-#include "Utility.h"
-
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Expression/UserExpression.h"
-#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
-#include "lldb/ValueObject/ValueObject.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-const char *address_sanitizer_retrieve_report_data_prefix = R"(
-extern "C"
-{
-int __asan_report_present();
-void *__asan_get_report_pc();
-void *__asan_get_report_bp();
-void *__asan_get_report_sp();
-void *__asan_get_report_address();
-const char *__asan_get_report_description();
-int __asan_get_report_access_type();
-size_t __asan_get_report_access_size();
-}
-)";
-
-const char *address_sanitizer_retrieve_report_data_command = R"(
-struct {
- int present;
- int access_type;
- void *pc;
- void *bp;
- void *sp;
- void *address;
- size_t access_size;
- const char *description;
-} t;
-
-t.present = __asan_report_present();
-t.access_type = __asan_get_report_access_type();
-t.pc = __asan_get_report_pc();
-t.bp = __asan_get_report_bp();
-t.sp = __asan_get_report_sp();
-t.address = __asan_get_report_address();
-t.access_size = __asan_get_report_access_size();
-t.description = __asan_get_report_description();
-t
-)";
-
-StructuredData::ObjectSP
-ReportRetriever::RetrieveReportData(const ProcessSP process_sp) {
- if (!process_sp)
- return StructuredData::ObjectSP();
-
- ThreadSP thread_sp =
- process_sp->GetThreadList().GetExpressionExecutionThread();
-
- if (!thread_sp)
- return StructuredData::ObjectSP();
-
- StackFrameSP frame_sp =
- thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
-
- if (!frame_sp)
- return StructuredData::ObjectSP();
-
- EvaluateExpressionOptions options;
- options.SetUnwindOnError(true);
- options.SetTryAllThreads(true);
- options.SetStopOthers(true);
- options.SetIgnoreBreakpoints(true);
- options.SetTimeout(process_sp->GetUtilityExpressionTimeout());
- options.SetPrefix(address_sanitizer_retrieve_report_data_prefix);
- options.SetAutoApplyFixIts(false);
- options.SetLanguage(eLanguageTypeC);
-
- if (auto [m, _] = GetPreferredAsanModule(process_sp->GetTarget()); m) {
- SymbolContextList sc_list;
- sc_list.Append(SymbolContext(std::move(m)));
- options.SetPreferredSymbolContexts(std::move(sc_list));
- }
-
- ValueObjectSP return_value_sp;
- ExecutionContext exe_ctx;
- frame_sp->CalculateExecutionContext(exe_ctx);
- ExpressionResults result = UserExpression::Evaluate(
- exe_ctx, options, address_sanitizer_retrieve_report_data_command, "",
- return_value_sp);
- if (result != eExpressionCompleted) {
- StreamString ss;
- ss << "cannot evaluate AddressSanitizer expression:\n";
- if (return_value_sp)
- ss << return_value_sp->GetError().AsCString();
- Debugger::ReportWarning(ss.GetString().str(),
- process_sp->GetTarget().GetDebugger().GetID());
- return StructuredData::ObjectSP();
- }
-
- int present = return_value_sp->GetValueForExpressionPath(".present")
- ->GetValueAsUnsigned(0);
- if (present != 1)
- return StructuredData::ObjectSP();
-
- addr_t pc =
- return_value_sp->GetValueForExpressionPath(".pc")->GetValueAsUnsigned(0);
- addr_t bp =
- return_value_sp->GetValueForExpressionPath(".bp")->GetValueAsUnsigned(0);
- addr_t sp =
- return_value_sp->GetValueForExpressionPath(".sp")->GetValueAsUnsigned(0);
- addr_t address = return_value_sp->GetValueForExpressionPath(".address")
- ->GetValueAsUnsigned(0);
- addr_t access_type =
- return_value_sp->GetValueForExpressionPath(".access_type")
- ->GetValueAsUnsigned(0);
- addr_t access_size =
- return_value_sp->GetValueForExpressionPath(".access_size")
- ->GetValueAsUnsigned(0);
- addr_t description_ptr =
- return_value_sp->GetValueForExpressionPath(".description")
- ->GetValueAsUnsigned(0);
- std::string description;
- Status error;
- process_sp->ReadCStringFromMemory(description_ptr, description, error);
-
- auto dict = std::make_shared<StructuredData::Dictionary>();
- if (!dict)
- return StructuredData::ObjectSP();
-
- dict->AddStringItem("instrumentation_class", "AddressSanitizer");
- dict->AddStringItem("stop_type", "fatal_error");
- dict->AddIntegerItem("pc", pc);
- dict->AddIntegerItem("bp", bp);
- dict->AddIntegerItem("sp", sp);
- dict->AddIntegerItem("address", address);
- dict->AddIntegerItem("access_type", access_type);
- dict->AddIntegerItem("access_size", access_size);
- dict->AddStringItem("description", description);
-
- return StructuredData::ObjectSP(dict);
-}
-
-std::string
-ReportRetriever::FormatDescription(StructuredData::ObjectSP report) {
- std::string description = std::string(report->GetAsDictionary()
- ->GetValueForKey("description")
- ->GetAsString()
- ->GetValue());
- return llvm::StringSwitch<std::string>(description)
- .Case("heap-use-after-free", "Use of deallocated memory")
- .Case("heap-buffer-overflow", "Heap buffer overflow")
- .Case("stack-buffer-underflow", "Stack buffer underflow")
- .Case("initialization-order-fiasco", "Initialization order problem")
- .Case("stack-buffer-overflow", "Stack buffer overflow")
- .Case("stack-use-after-return", "Use of stack memory after return")
- .Case("use-after-poison", "Use of poisoned memory")
- .Case("container-overflow", "Container overflow")
- .Case("stack-use-after-scope", "Use of out-of-scope stack memory")
- .Case("global-buffer-overflow", "Global buffer overflow")
- .Case("unknown-crash", "Invalid memory access")
- .Case("stack-overflow", "Stack space exhausted")
- .Case("null-deref", "Dereference of null pointer")
- .Case("wild-jump", "Jump to non-executable address")
- .Case("wild-addr-write", "Write through wild pointer")
- .Case("wild-addr-read", "Read from wild pointer")
- .Case("wild-addr", "Access through wild pointer")
- .Case("signal", "Deadly signal")
- .Case("double-free", "Deallocation of freed memory")
- .Case("new-delete-type-mismatch",
- "Deallocation size different from allocation size")
- .Case("bad-free", "Deallocation of non-allocated memory")
- .Case("alloc-dealloc-mismatch",
- "Mismatch between allocation and deallocation APIs")
- .Case("bad-malloc_usable_size", "Invalid argument to malloc_usable_size")
- .Case("bad-__sanitizer_get_allocated_size",
- "Invalid argument to __sanitizer_get_allocated_size")
- .Case("param-overlap",
- "Call to function disallowing overlapping memory ranges")
- .Case("negative-size-param", "Negative size used when accessing memory")
- .Case("bad-__sanitizer_annotate_contiguous_container",
- "Invalid argument to __sanitizer_annotate_contiguous_container")
- .Case("odr-violation", "Symbol defined in multiple translation units")
- .Case(
- "invalid-pointer-pair",
- "Comparison or arithmetic on pointers from different memory regions")
- // for unknown report codes just show the code
- .Default("AddressSanitizer detected: " + description);
-}
-
-bool ReportRetriever::NotifyBreakpointHit(ProcessSP process_sp,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id) {
- // Make sure this is the right process
- if (!process_sp || process_sp != context->exe_ctx_ref.GetProcessSP())
- return false;
-
- if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
- return false;
-
- StructuredData::ObjectSP report = RetrieveReportData(process_sp);
- if (!report || report->GetType() != lldb::eStructuredDataTypeDictionary) {
- LLDB_LOGF(GetLog(LLDBLog::InstrumentationRuntime),
- "ReportRetriever::RetrieveReportData() failed");
- return false;
- }
-
- std::string description = FormatDescription(report);
-
- if (ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP())
- thread_sp->SetStopInfo(
- InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(
- *thread_sp, description, report));
-
- if (StreamSP stream_sp =
- process_sp->GetTarget().GetDebugger().GetAsyncOutputStream())
- stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread "
- "info -s' to get extended information about the "
- "report.\n");
-
- return true; // Return true to stop the target
-}
-
-Breakpoint *ReportRetriever::SetupBreakpoint(ModuleSP module_sp,
- ProcessSP process_sp,
- ConstString symbol_name) {
- if (!module_sp || !process_sp)
- return nullptr;
-
- const Symbol *symbol =
- module_sp->FindFirstSymbolWithNameAndType(symbol_name, eSymbolTypeCode);
-
- if (symbol == nullptr)
- return nullptr;
-
- if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
- return nullptr;
-
- const Address &address = symbol->GetAddressRef();
- const bool internal = true;
- const bool hardware = false;
-
- Breakpoint *breakpoint = process_sp->GetTarget()
- .CreateBreakpoint(address, internal, hardware)
- .get();
-
- return breakpoint;
-}
diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h
deleted file mode 100644
index a45339a5809c0..0000000000000
--- a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===-- ReportRetriever.h ---------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Target/Process.h"
-
-#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_REPORTRETRIEVER_H
-#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_REPORTRETRIEVER_H
-
-namespace lldb_private {
-
-class ReportRetriever {
-private:
- static StructuredData::ObjectSP
- RetrieveReportData(const lldb::ProcessSP process_sp);
-
- static std::string FormatDescription(StructuredData::ObjectSP report);
-
-public:
- static bool NotifyBreakpointHit(lldb::ProcessSP process_sp,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
-
- static Breakpoint *SetupBreakpoint(lldb::ModuleSP, lldb::ProcessSP,
- ConstString);
-};
-} // namespace lldb_private
-
-#endif // LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_REPORTRETRIEVER_H
diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp
index 1700734e6e354..6f11e3a03c794 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp
@@ -15,7 +15,7 @@ namespace lldb_private {
std::tuple<lldb::ModuleSP, HistoryPCType>
GetPreferredAsanModule(const Target &target) {
- // Currently only Darwin provides ASan runtime support as part of the OS
+ // Currently only Darwin provides (partial) runtime support as part of the OS
// (libsanitizers).
if (!target.GetArchitecture().GetTriple().isOSDarwin())
return {nullptr, HistoryPCType::Calls};
diff --git a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
index e76544af143aa..f15d35f3954da 100644
--- a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
@@ -50,7 +50,7 @@ struct MainThreadCheckerReport {
std::string selector;
};
-// See `ReportRetriever::RetrieveReportData`.
+// See `InstrumentationRuntimeASan::RetrieveReportData`.
struct ASanReport {
std::string description;
lldb::addr_t address = LLDB_INVALID_ADDRESS;
More information about the lldb-commits
mailing list