Skip to content

Commit b25a5a0

Browse files
committed
[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
1 parent 026165f commit b25a5a0

File tree

4 files changed

+103
-5
lines changed

4 files changed

+103
-5
lines changed
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
C_SOURCES := main.c
2-
CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
2+
asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
3+
asan: all
4+
5+
libsanitizers: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
6+
libsanitizers: all
37

48
include Makefile.rules

lldb/test/API/functionalities/asan/TestMemoryHistory.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@
99
from lldbsuite.test import lldbplatform
1010
from lldbsuite.test import lldbutil
1111

12+
from functionalities.libsanitizers.util import no_libsanitizers
1213

1314
class AsanTestCase(TestBase):
1415
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
1516
@expectedFailureNetBSD
1617
@skipUnlessAddressSanitizer
1718
def test(self):
18-
self.build()
19+
self.build(make_targets=["asan"])
1920
self.asan_tests()
2021

22+
@skipIf(oslist=no_match(["macosx"]))
23+
@skipTestIfFn(no_libsanitizers)
24+
def test_libsanitizers_asan(self):
25+
self.build(make_targets=["libsanitizers"])
26+
self.libsanitizer_tests()
27+
2128
def setUp(self):
2229
# Call super's setUp().
2330
TestBase.setUp(self)
@@ -26,6 +33,68 @@ def setUp(self):
2633
self.line_free = line_number("main.c", "// free line")
2734
self.line_breakpoint = line_number("main.c", "// break line")
2835

36+
# Test line numbers: rdar://126237493
37+
def libsanitizer_tests(self):
38+
target = self.createTestTarget()
39+
40+
self.runCmd(
41+
"env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
42+
)
43+
44+
self.runCmd("run")
45+
46+
# In libsanitizers, memory history is not supported until a report has been generated
47+
self.expect(
48+
"thread list",
49+
"Process should be stopped due to ASan report",
50+
substrs=["stopped", "stop reason = Use of deallocated memory"],
51+
)
52+
53+
# test the 'memory history' command
54+
self.expect(
55+
"memory history 'pointer'",
56+
substrs=[
57+
"Memory deallocated by Thread",
58+
"a.out`f2",
59+
"main.c",
60+
"Memory allocated by Thread",
61+
"a.out`f1",
62+
"main.c",
63+
],
64+
)
65+
66+
# do the same using SB API
67+
process = self.dbg.GetSelectedTarget().process
68+
val = (
69+
process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer")
70+
)
71+
addr = val.GetValueAsUnsigned()
72+
threads = process.GetHistoryThreads(addr)
73+
self.assertEqual(threads.GetSize(), 2)
74+
75+
history_thread = threads.GetThreadAtIndex(0)
76+
self.assertTrue(history_thread.num_frames >= 2)
77+
self.assertEqual(
78+
history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
79+
"main.c",
80+
)
81+
82+
history_thread = threads.GetThreadAtIndex(1)
83+
self.assertTrue(history_thread.num_frames >= 2)
84+
self.assertEqual(
85+
history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
86+
"main.c",
87+
)
88+
89+
# let's free the container (SBThreadCollection) and see if the
90+
# SBThreads still live
91+
threads = None
92+
self.assertTrue(history_thread.num_frames >= 2)
93+
self.assertEqual(
94+
history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
95+
"main.c",
96+
)
97+
2998
def asan_tests(self):
3099
target = self.createTestTarget()
31100

lldb/test/API/functionalities/asan/TestReportData.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,23 @@
99
from lldbsuite.test.lldbtest import *
1010
from lldbsuite.test import lldbutil
1111

12+
from functionalities.libsanitizers.util import no_libsanitizers
1213

1314
class AsanTestReportDataCase(TestBase):
1415
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
1516
@expectedFailureNetBSD
1617
@skipUnlessAddressSanitizer
1718
@skipIf(archs=["i386"], bugnumber="llvm.org/PR36710")
1819
def test(self):
19-
self.build()
20+
self.build(make_targets=["asan"])
2021
self.asan_tests()
2122

23+
@skipIf(oslist=no_match(["macosx"]))
24+
@skipTestIfFn(no_libsanitizers)
25+
def test_libsanitizers_asan(self):
26+
self.build(make_targets=["libsanitizers"])
27+
self.asan_tests(libsanitizers=True)
28+
2229
def setUp(self):
2330
# Call super's setUp().
2431
TestBase.setUp(self)
@@ -29,10 +36,15 @@ def setUp(self):
2936
self.line_crash = line_number("main.c", "// BOOM line")
3037
self.col_crash = 16
3138

32-
def asan_tests(self):
39+
def asan_tests(self, libsanitizers=False):
3340
target = self.createTestTarget()
3441

35-
self.registerSanitizerLibrariesWithTarget(target)
42+
if libsanitizers:
43+
self.runCmd(
44+
"env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
45+
)
46+
else:
47+
self.registerSanitizerLibrariesWithTarget(target)
3648

3749
self.runCmd("run")
3850

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import subprocess
2+
3+
def no_libsanitizers():
4+
exe = shutil.which("dyld_shared_cache_util")
5+
if not exe:
6+
return "dyld_shared_cache_util not found"
7+
8+
libs = subprocess.check_output([exe, "-list"]).decode("utf-8")
9+
for line in libs.split("\n"):
10+
if "libsystem_sanitizers.dylib" in line:
11+
return None
12+
13+
return "libsystem_sanitizers.dylib not found in shared cache"

0 commit comments

Comments
 (0)