[Lldb-commits] [lldb] [LLDB] Add integration test for libsanitizers trace collection (PR #134323)

Julian Lettner via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 4 16:11:44 PDT 2025


https://github.com/yln updated https://github.com/llvm/llvm-project/pull/134323

>From 8aa5e0e7f97df7627187bbd8ad4b3df51c798f4f Mon Sep 17 00:00:00 2001
From: Julian Lettner <jlettner at apple.com>
Date: Thu, 3 Apr 2025 14:47:53 -0700
Subject: [PATCH 1/4] [LLDB] Update reason for why tests are disabled

---
 lldb/test/API/functionalities/asan/TestMemoryHistory.py | 6 ++----
 lldb/test/API/functionalities/asan/TestReportData.py    | 6 ++----
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index b04182a543719..c3f15aefb1d49 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -19,7 +19,7 @@ def test(self):
         self.asan_tests()
 
     @skipIf(oslist=no_match(["macosx"]))
-    @skipIf(bugnumber="rdar://144997976")
+    @skipIf(bugnumber="rdar://109913184&143590169")
     def test_libsanitizers_asan(self):
         try:
             self.build(make_targets=["libsanitizers"])
@@ -39,9 +39,7 @@ def setUp(self):
     def libsanitizer_tests(self):
         target = self.createTestTarget()
 
-        self.runCmd(
-            "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
-        )
+        self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
 
         self.runCmd("run")
 
diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py
index fabc985d0ed44..52ae199378f3b 100644
--- a/lldb/test/API/functionalities/asan/TestReportData.py
+++ b/lldb/test/API/functionalities/asan/TestReportData.py
@@ -20,7 +20,7 @@ def test(self):
         self.asan_tests()
 
     @skipIf(oslist=no_match(["macosx"]))
-    @skipIf(bugnumber="rdar://144997976")
+    @skipIf(bugnumber="rdar://109913184&143590169")
     def test_libsanitizers_asan(self):
         try:
             self.build(make_targets=["libsanitizers"])
@@ -42,9 +42,7 @@ def asan_tests(self, libsanitizers=False):
         target = self.createTestTarget()
 
         if libsanitizers:
-            self.runCmd(
-                "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
-            )
+            self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
         else:
             self.registerSanitizerLibrariesWithTarget(target)
 

>From 803214e7ccb5c45a58c90951481af3570bb4be9d Mon Sep 17 00:00:00 2001
From: Julian Lettner <jlettner at apple.com>
Date: Thu, 3 Apr 2025 16:07:04 -0700
Subject: [PATCH 2/4] [LLDB] Add integration test for libsanitizers trace
 collection

Add integration test for libsanitizers trace
collection (`SanitizersAllocationTraces=all`).

rdar://144244084
---
 lldb/test/API/functionalities/asan/Makefile   | 11 ++-
 .../functionalities/asan/TestMemoryHistory.py | 88 ++++++++++++-------
 .../functionalities/asan/TestReportData.py    |  6 +-
 3 files changed, 67 insertions(+), 38 deletions(-)

diff --git a/lldb/test/API/functionalities/asan/Makefile b/lldb/test/API/functionalities/asan/Makefile
index d66696fed7078..eae5ca3e4626c 100644
--- a/lldb/test/API/functionalities/asan/Makefile
+++ b/lldb/test/API/functionalities/asan/Makefile
@@ -1,8 +1,11 @@
 C_SOURCES := main.c
-asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
-asan: all
+compiler_rt-asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+compiler_rt-asan: all
 
-libsanitizers: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
-libsanitizers: 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
 
 include Makefile.rules
diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index c3f15aefb1d49..894235481c440 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -15,17 +15,23 @@ class AsanTestCase(TestBase):
     @expectedFailureNetBSD
     @skipUnlessAddressSanitizer
     def test(self):
-        self.build(make_targets=["asan"])
+        self.build(make_targets=["compiler_rt-asan"])
         self.asan_tests()
 
-    @skipIf(oslist=no_match(["macosx"]))
+    @skipUnlessDarwin
     @skipIf(bugnumber="rdar://109913184&143590169")
     def test_libsanitizers_asan(self):
         try:
-            self.build(make_targets=["libsanitizers"])
+            self.build(make_targets=["libsanitizers-asan"])
         except BuildError as e:
             self.skipTest("failed to build with libsanitizers")
-        self.libsanitizer_tests()
+        self.libsanitizers_asan_tests()
+
+    @skipUnlessDarwin
+    @skipIf(macos_version=["<", "15.5"])
+    def test_libsanitizers_traces(self):
+        self.build(make_targets=["libsanitizers-traces"])
+        self.libsanitizers_traces_tests()
 
     def setUp(self):
         # Call super's setUp().
@@ -36,32 +42,61 @@ def setUp(self):
         self.line_breakpoint = line_number("main.c", "// break line")
 
     # Test line numbers: rdar://126237493
-    def libsanitizer_tests(self):
-        target = self.createTestTarget()
+    # for libsanitizers and remove `skip_line_numbers` parameter
+    def check_traces(self, skip_line_numbers):
+        self.expect(
+            "memory history 'pointer'",
+            substrs=[
+                "Memory deallocated by Thread",
+                "a.out`f2",
+                "main.c" if skip_line_numbers else f"main.c:{self.line_free}",
+                "Memory allocated by Thread",
+                "a.out`f1",
+                "main.c" if skip_line_numbers else f"main.c:{self.line_malloc}",
+            ],
+        )
+
+    def libsanitizers_traces_tests(self):
+        self.createTestTarget()
+
+        self.runCmd("env SanitizersAllocationTraces=all")
+
+        self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
+        self.runCmd("run")
+
+        # Stop on breakpoint, before report
+        self.expect(
+            "thread list",
+            STOPPED_DUE_TO_BREAKPOINT,
+            substrs=["stopped", "stop reason = breakpoint"],
+        )
+        self.check_traces(skip_line_numbers=True)
+
+    def libsanitizers_asan_tests(self):
+        self.createTestTarget()
 
         self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
 
+        self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
         self.runCmd("run")
 
-        # In libsanitizers, memory history is not supported until a report has been generated
+        # Stop on breakpoint, before report
         self.expect(
             "thread list",
-            "Process should be stopped due to ASan report",
-            substrs=["stopped", "stop reason = Use of deallocated memory"],
+            STOPPED_DUE_TO_BREAKPOINT,
+            substrs=["stopped", "stop reason = breakpoint"],
         )
+        self.check_traces(skip_line_numbers=True)
 
-        # test the 'memory history' command
+        self.runCmd("continue")
+
+        # Stop on report
         self.expect(
-            "memory history 'pointer'",
-            substrs=[
-                "Memory deallocated by Thread",
-                "a.out`f2",
-                "main.c",
-                "Memory allocated by Thread",
-                "a.out`f1",
-                "main.c",
-            ],
+            "thread list",
+            "Process should be stopped due to ASan report",
+            substrs=["stopped", "stop reason = Use of deallocated memory"],
         )
+        self.check_traces(skip_line_numbers=True)
 
         # do the same using SB API
         process = self.dbg.GetSelectedTarget().process
@@ -133,18 +168,7 @@ def asan_tests(self):
             substrs=["1 match found"],
         )
 
-        # test the 'memory history' command
-        self.expect(
-            "memory history 'pointer'",
-            substrs=[
-                "Memory deallocated by Thread",
-                "a.out`f2",
-                "main.c:%d" % self.line_free,
-                "Memory allocated by Thread",
-                "a.out`f1",
-                "main.c:%d" % self.line_malloc,
-            ],
-        )
+        self.check_traces()
 
         # do the same using SB API
         process = self.dbg.GetSelectedTarget().process
@@ -196,6 +220,8 @@ def asan_tests(self):
             substrs=["stopped", "stop reason = Use of deallocated memory"],
         )
 
+        self.check_traces()
+
         # make sure the 'memory history' command still works even when we're
         # generating a report now
         self.expect(
diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py
index 52ae199378f3b..dd6834a01b80c 100644
--- a/lldb/test/API/functionalities/asan/TestReportData.py
+++ b/lldb/test/API/functionalities/asan/TestReportData.py
@@ -16,14 +16,14 @@ class AsanTestReportDataCase(TestBase):
     @skipUnlessAddressSanitizer
     @skipIf(archs=["i386"], bugnumber="llvm.org/PR36710")
     def test(self):
-        self.build(make_targets=["asan"])
+        self.build(make_targets=["compiler_rt-asan"])
         self.asan_tests()
 
-    @skipIf(oslist=no_match(["macosx"]))
+    @skipUnlessDarwin
     @skipIf(bugnumber="rdar://109913184&143590169")
     def test_libsanitizers_asan(self):
         try:
-            self.build(make_targets=["libsanitizers"])
+            self.build(make_targets=["libsanitizers-asan"])
         except BuildError as e:
             self.skipTest("failed to build with libsanitizers")
         self.asan_tests(libsanitizers=True)

>From f27d4a1d35f80f8d8dda78a5edcf98cf058dc955 Mon Sep 17 00:00:00 2001
From: Julian Lettner <jlettner at apple.com>
Date: Fri, 4 Apr 2025 14:46:30 -0700
Subject: [PATCH 3/4] [LLDB] Address review feedback

* Consistent function names
* Extract function for setting and running to
  breakpoint
---
 .../functionalities/asan/TestMemoryHistory.py | 41 +++++++++----------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index 894235481c440..6c66d1cea349b 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -10,13 +10,13 @@
 from lldbsuite.test import lldbutil
 from lldbsuite.test_event.build_exception import BuildError
 
-class AsanTestCase(TestBase):
+class MemoryHistoryTestCase(TestBase):
     @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default
     @expectedFailureNetBSD
     @skipUnlessAddressSanitizer
-    def test(self):
+    def test_compiler_rt_asan(self):
         self.build(make_targets=["compiler_rt-asan"])
-        self.asan_tests()
+        self.compiler_rt_asan_tests()
 
     @skipUnlessDarwin
     @skipIf(bugnumber="rdar://109913184&143590169")
@@ -43,7 +43,7 @@ def setUp(self):
 
     # Test line numbers: rdar://126237493
     # for libsanitizers and remove `skip_line_numbers` parameter
-    def check_traces(self, skip_line_numbers):
+    def check_traces(self, skip_line_numbers=False):
         self.expect(
             "memory history 'pointer'",
             substrs=[
@@ -56,20 +56,25 @@ def check_traces(self, skip_line_numbers):
             ],
         )
 
-    def libsanitizers_traces_tests(self):
-        self.createTestTarget()
+    # Set breakpoint after free, but before bug
+    def set_breakpoint(self):
+        self.runCmd(f"breakpoint set -f main.c -l {self.line_breakpoint}")
 
-        self.runCmd("env SanitizersAllocationTraces=all")
-
-        self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
+    def run_to_breakpoint(self):
+        self.set_breakpoint()
         self.runCmd("run")
-
-        # Stop on breakpoint, before report
         self.expect(
             "thread list",
             STOPPED_DUE_TO_BREAKPOINT,
             substrs=["stopped", "stop reason = breakpoint"],
         )
+
+    def libsanitizers_traces_tests(self):
+        self.createTestTarget()
+
+        self.runCmd("env SanitizersAllocationTraces=all")
+
+        self.run_to_breakpoint()
         self.check_traces(skip_line_numbers=True)
 
     def libsanitizers_asan_tests(self):
@@ -77,15 +82,7 @@ def libsanitizers_asan_tests(self):
 
         self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
 
-        self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
-        self.runCmd("run")
-
-        # Stop on breakpoint, before report
-        self.expect(
-            "thread list",
-            STOPPED_DUE_TO_BREAKPOINT,
-            substrs=["stopped", "stop reason = breakpoint"],
-        )
+        self.run_to_breakpoint()
         self.check_traces(skip_line_numbers=True)
 
         self.runCmd("continue")
@@ -130,12 +127,12 @@ def libsanitizers_asan_tests(self):
             "main.c",
         )
 
-    def asan_tests(self):
+    def compiler_rt_asan_tests(self):
         target = self.createTestTarget()
 
         self.registerSanitizerLibrariesWithTarget(target)
 
-        self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
+        self.set_breakpoint()
 
         # "memory history" command should not work without a process
         self.expect(

>From 7d652144a9c12de628ee92479c99d16c746a23a9 Mon Sep 17 00:00:00 2001
From: Julian Lettner <jlettner at apple.com>
Date: Fri, 4 Apr 2025 16:05:24 -0700
Subject: [PATCH 4/4] [LLDB] Set breakpoint in a way that is more robust

---
 .../functionalities/asan/TestMemoryHistory.py | 23 +++++++++++--------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index 6c66d1cea349b..27f725d857f1e 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -56,12 +56,15 @@ def check_traces(self, skip_line_numbers=False):
             ],
         )
 
-    # Set breakpoint after free, but before bug
-    def set_breakpoint(self):
-        self.runCmd(f"breakpoint set -f main.c -l {self.line_breakpoint}")
+    # Set breakpoint: after free, but before bug
+    def set_breakpoint(self, target):
+        bkpt = target.BreakpointCreateByLocation("main.c", self.line_breakpoint)
+        self.assertGreater(
+            bkpt.GetNumLocations(), 0, "Set the breakpoint successfully"
+        )
 
-    def run_to_breakpoint(self):
-        self.set_breakpoint()
+    def run_to_breakpoint(self, target):
+        self.set_breakpoint(target)
         self.runCmd("run")
         self.expect(
             "thread list",
@@ -70,19 +73,19 @@ def run_to_breakpoint(self):
         )
 
     def libsanitizers_traces_tests(self):
-        self.createTestTarget()
+        target = self.createTestTarget()
 
         self.runCmd("env SanitizersAllocationTraces=all")
 
-        self.run_to_breakpoint()
+        self.run_to_breakpoint(target)
         self.check_traces(skip_line_numbers=True)
 
     def libsanitizers_asan_tests(self):
-        self.createTestTarget()
+        target = self.createTestTarget()
 
         self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")
 
-        self.run_to_breakpoint()
+        self.run_to_breakpoint(target)
         self.check_traces(skip_line_numbers=True)
 
         self.runCmd("continue")
@@ -132,7 +135,7 @@ def compiler_rt_asan_tests(self):
 
         self.registerSanitizerLibrariesWithTarget(target)
 
-        self.set_breakpoint()
+        self.set_breakpoint(target)
 
         # "memory history" command should not work without a process
         self.expect(



More information about the lldb-commits mailing list