[Lldb-commits] [lldb] [lldb-dap] Add ASan report (PR #178858)
Sergei Druzhkov via lldb-commits
lldb-commits at lists.llvm.org
Fri Jan 30 02:17:21 PST 2026
https://github.com/DrSergei created https://github.com/llvm/llvm-project/pull/178858
Added `ASanReport` for `ExceptionInfo` request.
>From a89784b006c4158765021d8a7e83d7b1c44836c9 Mon Sep 17 00:00:00 2001
From: Sergei Druzhkov <serzhdruzhok at gmail.com>
Date: Fri, 30 Jan 2026 13:11:45 +0300
Subject: [PATCH] [lldb-dap] Add ASan report
---
.../tools/lldb-dap/exception/asan/Makefile | 4 ++
.../lldb-dap/exception/asan/TestDAP_asan.py | 24 ++++++++++
.../{runtime-instruments => asan}/categories | 0
.../tools/lldb-dap/exception/asan/main.cpp | 5 ++
.../{runtime-instruments => ubsan}/Makefile | 0
.../TestDAP_ubsan.py} | 6 +--
.../tools/lldb-dap/exception/ubsan/categories | 1 +
.../{runtime-instruments => ubsan}/main.c | 0
.../Handler/ExceptionInfoRequestHandler.cpp | 48 ++++++++++++++++++-
9 files changed, 84 insertions(+), 4 deletions(-)
create mode 100644 lldb/test/API/tools/lldb-dap/exception/asan/Makefile
create mode 100644 lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
rename lldb/test/API/tools/lldb-dap/exception/{runtime-instruments => asan}/categories (100%)
create mode 100644 lldb/test/API/tools/lldb-dap/exception/asan/main.cpp
rename lldb/test/API/tools/lldb-dap/exception/{runtime-instruments => ubsan}/Makefile (100%)
rename lldb/test/API/tools/lldb-dap/exception/{runtime-instruments/TestDAP_runtime_instruments.py => ubsan/TestDAP_ubsan.py} (80%)
create mode 100644 lldb/test/API/tools/lldb-dap/exception/ubsan/categories
rename lldb/test/API/tools/lldb-dap/exception/{runtime-instruments => ubsan}/main.c (100%)
diff --git a/lldb/test/API/tools/lldb-dap/exception/asan/Makefile b/lldb/test/API/tools/lldb-dap/exception/asan/Makefile
new file mode 100644
index 0000000000000..c9a415e9bd585
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/exception/asan/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -fsanitize=address -g
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py b/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
new file mode 100644
index 0000000000000..a87d7d72d8578
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/exception/asan/TestDAP_asan.py
@@ -0,0 +1,24 @@
+"""
+Test that we stop at runtime instrumentation locations (asan).
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+import lldbdap_testcase
+
+
+class TestDAP_asan(lldbdap_testcase.DAPTestCaseBase):
+ @skipUnlessAddressSanitizer
+ def test_asan(self):
+ """
+ Test that we stop at asan.
+ """
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ self.do_continue()
+
+ self.verify_stop_exception_info("Use of deallocated memory")
+ exceptionInfo = self.get_exceptionInfo()
+ self.assertEqual(exceptionInfo["breakMode"], "always")
+ self.assertRegex(exceptionInfo["description"], r"fatal_error: heap-use-after-free")
+ self.assertEqual(exceptionInfo["exceptionId"], "runtime-instrumentation")
diff --git a/lldb/test/API/tools/lldb-dap/exception/runtime-instruments/categories b/lldb/test/API/tools/lldb-dap/exception/asan/categories
similarity index 100%
rename from lldb/test/API/tools/lldb-dap/exception/runtime-instruments/categories
rename to lldb/test/API/tools/lldb-dap/exception/asan/categories
diff --git a/lldb/test/API/tools/lldb-dap/exception/asan/main.cpp b/lldb/test/API/tools/lldb-dap/exception/asan/main.cpp
new file mode 100644
index 0000000000000..526d3913a7932
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/exception/asan/main.cpp
@@ -0,0 +1,5 @@
+int main() {
+ int *array = new int[100];
+ delete [] array;
+ return array[42]; // asan
+}
diff --git a/lldb/test/API/tools/lldb-dap/exception/runtime-instruments/Makefile b/lldb/test/API/tools/lldb-dap/exception/ubsan/Makefile
similarity index 100%
rename from lldb/test/API/tools/lldb-dap/exception/runtime-instruments/Makefile
rename to lldb/test/API/tools/lldb-dap/exception/ubsan/Makefile
diff --git a/lldb/test/API/tools/lldb-dap/exception/runtime-instruments/TestDAP_runtime_instruments.py b/lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py
similarity index 80%
rename from lldb/test/API/tools/lldb-dap/exception/runtime-instruments/TestDAP_runtime_instruments.py
rename to lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py
index ffc02c9b60fd7..270c7f0a22a89 100644
--- a/lldb/test/API/tools/lldb-dap/exception/runtime-instruments/TestDAP_runtime_instruments.py
+++ b/lldb/test/API/tools/lldb-dap/exception/ubsan/TestDAP_ubsan.py
@@ -1,5 +1,5 @@
"""
-Test that we stop at runtime instrumentation locations.
+Test that we stop at runtime instrumentation locations (ubsan).
"""
from lldbsuite.test.decorators import *
@@ -7,7 +7,7 @@
import lldbdap_testcase
-class TestDAP_runtime_instruments(lldbdap_testcase.DAPTestCaseBase):
+class TestDAP_ubsan(lldbdap_testcase.DAPTestCaseBase):
@skipUnlessUndefinedBehaviorSanitizer
def test_ubsan(self):
"""
@@ -23,7 +23,7 @@ def test_ubsan(self):
self.assertRegex(exceptionInfo["description"], r"Out of bounds index")
self.assertEqual(exceptionInfo["exceptionId"], "runtime-instrumentation")
- # FIXME: Check on non macOS platform the stop infomation location heuristic
+ # FIXME: Check on non macOS platform the stop information location heuristic
# may be wrong. enable when we have updated Ubsan stopInfo heuristic.
if self.platformIsDarwin():
self.assertIn("main.c", exceptionInfo["details"]["stackTrace"])
diff --git a/lldb/test/API/tools/lldb-dap/exception/ubsan/categories b/lldb/test/API/tools/lldb-dap/exception/ubsan/categories
new file mode 100644
index 0000000000000..c756cb1241945
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/exception/ubsan/categories
@@ -0,0 +1 @@
+instrumentation-runtime
diff --git a/lldb/test/API/tools/lldb-dap/exception/runtime-instruments/main.c b/lldb/test/API/tools/lldb-dap/exception/ubsan/main.c
similarity index 100%
rename from lldb/test/API/tools/lldb-dap/exception/runtime-instruments/main.c
rename to lldb/test/API/tools/lldb-dap/exception/ubsan/main.c
diff --git a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
index 3a96533c9cd12..745c9d22c6690 100644
--- a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
@@ -19,6 +19,7 @@
#include "lldb/API/SBValue.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Error.h"
@@ -49,10 +50,20 @@ struct MainThreadCheckerReport {
std::string selector;
};
+// See `ReportRetriever::RetrieveReportData`.
+struct ASanReport {
+ std::string description;
+ lldb::addr_t address = LLDB_INVALID_ADDRESS;
+ lldb::addr_t pc = LLDB_INVALID_ADDRESS;
+ lldb::addr_t bp = LLDB_INVALID_ADDRESS;
+ lldb::addr_t sp = LLDB_INVALID_ADDRESS;
+ std::string stop_type;
+};
+
// FIXME: Support TSan, ASan, BoundsSafety formatting.
using RuntimeInstrumentReport =
- std::variant<UBSanReport, MainThreadCheckerReport>;
+ std::variant<UBSanReport, MainThreadCheckerReport, ASanReport>;
static bool fromJSON(const json::Value ¶ms, UBSanReport &report,
json::Path path) {
@@ -73,6 +84,16 @@ static bool fromJSON(const json::Value ¶ms, MainThreadCheckerReport &report,
O.mapOptional("selector", report.selector);
}
+static bool fromJSON(const json::Value ¶ms, ASanReport &report,
+ json::Path path) {
+ json::ObjectMapper O(params, path);
+ return O.mapOptional("description", report.description) &&
+ O.mapOptional("address", report.address) &&
+ O.mapOptional("pc", report.pc) && O.mapOptional("bp", report.bp) &&
+ O.mapOptional("sp", report.sp) &&
+ O.mapOptional("stop_type", report.stop_type);
+}
+
static bool fromJSON(const json::Value ¶ms, RuntimeInstrumentReport &report,
json::Path path) {
json::ObjectMapper O(params, path);
@@ -94,6 +115,13 @@ static bool fromJSON(const json::Value ¶ms, RuntimeInstrumentReport &report,
report = std::move(inner_report);
return success;
}
+ if (instrumentation_class == "AddressSanitizer") {
+ ASanReport inner_report;
+ bool success = fromJSON(params, inner_report, path);
+ if (success)
+ report = std::move(inner_report);
+ return success;
+ }
// FIXME: Support additional runtime instruments with specific formatters.
return false;
@@ -134,6 +162,24 @@ static raw_ostream &operator<<(raw_ostream &OS,
return OS;
}
+static raw_ostream &operator<<(raw_ostream &OS, ASanReport &report) {
+ if (!report.stop_type.empty())
+ OS << report.stop_type << ": ";
+ if (!report.description.empty())
+ OS << report.description << "\n";
+
+ if (report.address != LLDB_INVALID_ADDRESS)
+ OS << "Address: 0x" << llvm::utohexstr(report.address) << "\n";
+ if (report.pc != LLDB_INVALID_ADDRESS)
+ OS << "Program counter: 0x" << llvm::utohexstr(report.pc) << "\n";
+ if (report.bp != LLDB_INVALID_ADDRESS)
+ OS << "Base pointer: 0x" << llvm::utohexstr(report.bp) << "\n";
+ if (report.sp != LLDB_INVALID_ADDRESS)
+ OS << "Stack pointer: 0x" << llvm::utohexstr(report.sp) << "\n";
+
+ return OS;
+}
+
static raw_ostream &operator<<(raw_ostream &OS,
RuntimeInstrumentReport &report) {
std::visit([&](auto &r) { OS << r; }, report);
More information about the lldb-commits
mailing list