199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTests basic UndefinedBehaviorSanitizer support (detecting an alignment error).
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtimport os
699451b44SJordan Rupprechtimport lldb
799451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil
1099451b44SJordan Rupprechtimport json
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprechtclass UbsanBasicTestCase(TestBase):
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    @skipUnlessUndefinedBehaviorSanitizer
16*5f2e8f57SJonas Devlieghere    @no_debug_info_test
1799451b44SJordan Rupprecht    def test(self):
1899451b44SJordan Rupprecht        self.build()
1999451b44SJordan Rupprecht        self.ubsan_tests()
2099451b44SJordan Rupprecht
2199451b44SJordan Rupprecht    def setUp(self):
2299451b44SJordan Rupprecht        # Call super's setUp().
2399451b44SJordan Rupprecht        TestBase.setUp(self)
2499451b44SJordan Rupprecht        self.line_align = line_number('main.c', '// align line')
2599451b44SJordan Rupprecht
2699451b44SJordan Rupprecht    def ubsan_tests(self):
2799451b44SJordan Rupprecht        # Load the test
2899451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
293a538de6SJonas Devlieghere        target = self.dbg.CreateTarget(exe)
303a538de6SJonas Devlieghere        self.assertTrue(target, VALID_TARGET)
313a538de6SJonas Devlieghere        self.registerSanitizerLibrariesWithTarget(target)
3299451b44SJordan Rupprecht
3399451b44SJordan Rupprecht        self.runCmd("run")
3499451b44SJordan Rupprecht
3599451b44SJordan Rupprecht        process = self.dbg.GetSelectedTarget().process
3699451b44SJordan Rupprecht        thread = process.GetSelectedThread()
3799451b44SJordan Rupprecht        frame = thread.GetSelectedFrame()
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht        # the stop reason of the thread should be breakpoint.
4099451b44SJordan Rupprecht        self.expect("thread list", "A ubsan issue should be detected",
4199451b44SJordan Rupprecht                    substrs=['stopped', 'stop reason ='])
4299451b44SJordan Rupprecht
4399451b44SJordan Rupprecht        stop_reason = thread.GetStopReason()
4499451b44SJordan Rupprecht        self.assertEqual(stop_reason, lldb.eStopReasonInstrumentation)
4599451b44SJordan Rupprecht
4699451b44SJordan Rupprecht        # test that the UBSan dylib is present
4799451b44SJordan Rupprecht        self.expect(
4899451b44SJordan Rupprecht            "image lookup -n __ubsan_on_report",
4999451b44SJordan Rupprecht            "__ubsan_on_report should be present",
5099451b44SJordan Rupprecht            substrs=['1 match found'])
5199451b44SJordan Rupprecht
5299451b44SJordan Rupprecht        # We should be stopped in __ubsan_on_report
533cc37622SDave Lee        self.assertIn("__ubsan_on_report", frame.GetFunctionName())
5499451b44SJordan Rupprecht
5599451b44SJordan Rupprecht        # The stopped thread backtrace should contain either 'align line'
5699451b44SJordan Rupprecht        found = False
5799451b44SJordan Rupprecht        for i in range(thread.GetNumFrames()):
5899451b44SJordan Rupprecht            frame = thread.GetFrameAtIndex(i)
5999451b44SJordan Rupprecht            if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
6099451b44SJordan Rupprecht                if frame.GetLineEntry().GetLine() == self.line_align:
6199451b44SJordan Rupprecht                    found = True
6299451b44SJordan Rupprecht        self.assertTrue(found)
6399451b44SJordan Rupprecht
6499451b44SJordan Rupprecht        backtraces = thread.GetStopReasonExtendedBacktraces(
6599451b44SJordan Rupprecht            lldb.eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer)
66b3a0c4d7SRaphael Isemann        self.assertEquals(backtraces.GetSize(), 1)
6799451b44SJordan Rupprecht
6899451b44SJordan Rupprecht        self.expect(
6999451b44SJordan Rupprecht            "thread info -s",
7099451b44SJordan Rupprecht            "The extended stop info should contain the UBSan provided fields",
7199451b44SJordan Rupprecht            substrs=[
7299451b44SJordan Rupprecht                "col",
7399451b44SJordan Rupprecht                "description",
7499451b44SJordan Rupprecht                "filename",
7599451b44SJordan Rupprecht                "instrumentation_class",
7699451b44SJordan Rupprecht                "line",
7799451b44SJordan Rupprecht                "memory_address",
7899451b44SJordan Rupprecht            ])
7999451b44SJordan Rupprecht
8099451b44SJordan Rupprecht        output_lines = self.res.GetOutput().split('\n')
8199451b44SJordan Rupprecht        json_line = '\n'.join(output_lines[2:])
8299451b44SJordan Rupprecht        data = json.loads(json_line)
8399451b44SJordan Rupprecht
8499451b44SJordan Rupprecht        self.assertEqual(data["instrumentation_class"], "UndefinedBehaviorSanitizer")
8599451b44SJordan Rupprecht        self.assertEqual(data["description"], "misaligned-pointer-use")
8699451b44SJordan Rupprecht        self.assertEqual(os.path.basename(data["filename"]), "main.c")
8799451b44SJordan Rupprecht        self.assertEqual(data["line"], self.line_align)
8899451b44SJordan Rupprecht
8999451b44SJordan Rupprecht        self.runCmd("continue")
90