[Lldb-commits] [lldb] Add asan tests for libsanitizers. (PR #88349)
Usama Hameed via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 11 11:40:48 PDT 2024
https://github.com/usama54321 updated https://github.com/llvm/llvm-project/pull/88349
>From b25a5a0b5beb249c8a646cbfc02b865ca91ab861 Mon Sep 17 00:00:00 2001
From: usama <u_hameed at apple.com>
Date: Wed, 10 Apr 2024 21:07:11 -0700
Subject: [PATCH] [LLDB] Add asan tests for libsanitizers.
This patch tests LLDB integration with libsanitizers for ASan. This
integration works through the ASanLibsanitizers plugin in the
InstrumentationRuntime.
rdar://111856681
---
lldb/test/API/functionalities/asan/Makefile | 6 +-
.../functionalities/asan/TestMemoryHistory.py | 71 ++++++++++++++++++-
.../functionalities/asan/TestReportData.py | 18 ++++-
.../API/functionalities/libsanitizers/util.py | 13 ++++
4 files changed, 103 insertions(+), 5 deletions(-)
create mode 100644 lldb/test/API/functionalities/libsanitizers/util.py
diff --git a/lldb/test/API/functionalities/asan/Makefile b/lldb/test/API/functionalities/asan/Makefile
index 4913a18d8cc6f9..d66696fed7078f 100644
--- a/lldb/test/API/functionalities/asan/Makefile
+++ b/lldb/test/API/functionalities/asan/Makefile
@@ -1,4 +1,8 @@
C_SOURCES := main.c
-CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+asan: all
+
+libsanitizers: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
+libsanitizers: all
include Makefile.rules
diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index 00162ae8822c74..80961984174df7 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -9,15 +9,22 @@
from lldbsuite.test import lldbplatform
from lldbsuite.test import lldbutil
+from functionalities.libsanitizers.util import no_libsanitizers
class AsanTestCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@expectedFailureNetBSD
@skipUnlessAddressSanitizer
def test(self):
- self.build()
+ self.build(make_targets=["asan"])
self.asan_tests()
+ @skipIf(oslist=no_match(["macosx"]))
+ @skipTestIfFn(no_libsanitizers)
+ def test_libsanitizers_asan(self):
+ self.build(make_targets=["libsanitizers"])
+ self.libsanitizer_tests()
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -26,6 +33,68 @@ def setUp(self):
self.line_free = line_number("main.c", "// free line")
self.line_breakpoint = line_number("main.c", "// break line")
+ # Test line numbers: rdar://126237493
+ def libsanitizer_tests(self):
+ target = self.createTestTarget()
+
+ self.runCmd(
+ "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
+ )
+
+ self.runCmd("run")
+
+ # In libsanitizers, memory history is not supported until a report has been generated
+ self.expect(
+ "thread list",
+ "Process should be stopped due to ASan report",
+ substrs=["stopped", "stop reason = Use of deallocated memory"],
+ )
+
+ # test the 'memory history' command
+ self.expect(
+ "memory history 'pointer'",
+ substrs=[
+ "Memory deallocated by Thread",
+ "a.out`f2",
+ "main.c",
+ "Memory allocated by Thread",
+ "a.out`f1",
+ "main.c",
+ ],
+ )
+
+ # 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 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 543c5fe66a208d..43bcbedb56d4c9 100644
--- a/lldb/test/API/functionalities/asan/TestReportData.py
+++ b/lldb/test/API/functionalities/asan/TestReportData.py
@@ -9,6 +9,7 @@
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+from functionalities.libsanitizers.util import no_libsanitizers
class AsanTestReportDataCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@@ -16,9 +17,15 @@ class AsanTestReportDataCase(TestBase):
@skipUnlessAddressSanitizer
@skipIf(archs=["i386"], bugnumber="llvm.org/PR36710")
def test(self):
- self.build()
+ self.build(make_targets=["asan"])
self.asan_tests()
+ @skipIf(oslist=no_match(["macosx"]))
+ @skipTestIfFn(no_libsanitizers)
+ def test_libsanitizers_asan(self):
+ self.build(make_targets=["libsanitizers"])
+ self.asan_tests(libsanitizers=True)
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -29,10 +36,15 @@ def setUp(self):
self.line_crash = line_number("main.c", "// BOOM line")
self.col_crash = 16
- def asan_tests(self):
+ def asan_tests(self, libsanitizers=False):
target = self.createTestTarget()
- self.registerSanitizerLibrariesWithTarget(target)
+ if libsanitizers:
+ self.runCmd(
+ "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
+ )
+ else:
+ self.registerSanitizerLibrariesWithTarget(target)
self.runCmd("run")
diff --git a/lldb/test/API/functionalities/libsanitizers/util.py b/lldb/test/API/functionalities/libsanitizers/util.py
new file mode 100644
index 00000000000000..00ec95d2019b7e
--- /dev/null
+++ b/lldb/test/API/functionalities/libsanitizers/util.py
@@ -0,0 +1,13 @@
+import subprocess
+
+def no_libsanitizers():
+ exe = shutil.which("dyld_shared_cache_util")
+ if not exe:
+ return "dyld_shared_cache_util not found"
+
+ libs = subprocess.check_output([exe, "-list"]).decode("utf-8")
+ for line in libs.split("\n"):
+ if "libsystem_sanitizers.dylib" in line:
+ return None
+
+ return "libsystem_sanitizers.dylib not found in shared cache"
More information about the lldb-commits
mailing list