Michael Buch 59db71c7bd [lldb][test] Re-enable and fix TestUbsanBasic.py
UBSAN stopped reporting the misaligned load since 5569bf26f0 so this test started failing. We skipped it to unblock CI.

There's been discussion on making UBSAN stricter and still trigger on
the one-line version of this. But for now, to get the test running
again, change it to a form which *does* trigger UBSAN.

Fixes https://github.com/llvm/llvm-project/issues/177064
2026-01-22 09:28:47 +00:00

105 lines
3.4 KiB
Python

"""
Tests basic UndefinedBehaviorSanitizer support (detecting an alignment error).
"""
import os
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import json
class UbsanBasicTestCase(TestBase):
@skipUnlessUndefinedBehaviorSanitizer
@no_debug_info_test
def test(self):
self.build()
self.ubsan_tests()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.line_align = line_number("main.c", "// align line")
def ubsan_tests(self):
# Load the test
exe = self.getBuildArtifact("a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
self.registerSanitizerLibrariesWithTarget(target)
self.runCmd("run")
process = self.dbg.GetSelectedTarget().process
thread = process.GetSelectedThread()
frame = thread.GetSelectedFrame()
# the stop reason of the thread should be breakpoint.
self.expect(
"thread list",
"A ubsan issue should be detected",
substrs=["stopped", "stop reason ="],
)
stop_reason = thread.GetStopReason()
self.assertStopReason(stop_reason, lldb.eStopReasonInstrumentation)
# test that the UBSan dylib is present
self.expect(
"image lookup -n __ubsan_on_report",
"__ubsan_on_report should be present",
substrs=["1 match found"],
)
if self.platformIsDarwin():
# We should not be stopped in the sanitizer library.
self.assertIn("main", frame.GetFunctionName())
else:
self.assertIn("__ubsan_on_report", frame.GetFunctionName())
# The stopped thread backtrace should contain either 'align line'
found = False
for i in range(thread.GetNumFrames()):
frame = thread.GetFrameAtIndex(i)
if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
if frame.GetLineEntry().GetLine() == self.line_align:
found = True
self.assertTrue(found)
backtraces = thread.GetStopReasonExtendedBacktraces(
lldb.eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer
)
self.assertEqual(backtraces.GetSize(), 1)
self.expect(
"thread info -s",
"The extended stop info should contain the UBSan provided fields",
substrs=[
"col",
"description",
"filename",
"instrumentation_class",
"line",
"memory_address",
],
)
output_lines = self.res.GetOutput().split("\n")
json_line = "\n".join(output_lines[2:])
data = json.loads(json_line)
self.assertEqual(data["instrumentation_class"], "UndefinedBehaviorSanitizer")
self.assertEqual(data["description"], "misaligned-pointer-use")
self.assertEqual(os.path.basename(data["filename"]), "main.c")
self.assertEqual(data["line"], self.line_align)
for count in range(0, 8):
process.Continue()
stop_reason = thread.GetStopReason()
self.assertEqual(
stop_reason,
lldb.eStopReasonInstrumentation,
"Round {0} wasn't instrumentation".format(count),
)