• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Test the AddressSanitizer runtime support for report breakpoint and data extraction.
3"""
4
5
6
7import json
8import lldb
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import lldbutil
12
13
14class AsanTestReportDataCase(TestBase):
15
16    mydir = TestBase.compute_mydir(__file__)
17
18    @skipIfFreeBSD  # llvm.org/pr21136 runtimes not yet available by default
19    @expectedFailureNetBSD
20    @skipUnlessAddressSanitizer
21    @skipIf(archs=['i386'], bugnumber="llvm.org/PR36710")
22    def test(self):
23        self.build()
24        self.asan_tests()
25
26    def setUp(self):
27        # Call super's setUp().
28        TestBase.setUp(self)
29        self.line_malloc = line_number('main.c', '// malloc line')
30        self.line_malloc2 = line_number('main.c', '// malloc2 line')
31        self.line_free = line_number('main.c', '// free line')
32        self.line_breakpoint = line_number('main.c', '// break line')
33        self.line_crash = line_number('main.c', '// BOOM line')
34        self.col_crash = 16
35
36    def asan_tests(self):
37        exe = self.getBuildArtifact("a.out")
38        target = self.dbg.CreateTarget(exe)
39        self.assertTrue(target, VALID_TARGET)
40
41        self.registerSanitizerLibrariesWithTarget(target)
42
43        self.runCmd("run")
44
45        stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()
46        if stop_reason == lldb.eStopReasonExec:
47            # On OS X 10.10 and older, we need to re-exec to enable
48            # interceptors.
49            self.runCmd("continue")
50
51        self.expect(
52            "thread list",
53            "Process should be stopped due to ASan report",
54            substrs=[
55                'stopped',
56                'stop reason = Use of deallocated memory'])
57
58        self.assertEqual(
59            self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),
60            lldb.eStopReasonInstrumentation)
61
62        self.expect("bt", "The backtrace should show the crashing line",
63                    substrs=['main.c:%d:%d' % (self.line_crash, self.col_crash)])
64
65        self.expect(
66            "thread info -s",
67            "The extended stop info should contain the ASan provided fields",
68            substrs=[
69                "access_size",
70                "access_type",
71                "address",
72                "description",
73                "heap-use-after-free",
74                "pc",
75            ])
76
77        output_lines = self.res.GetOutput().split('\n')
78        json_line = '\n'.join(output_lines[2:])
79        data = json.loads(json_line)
80        self.assertEqual(data["description"], "heap-use-after-free")
81        self.assertEqual(data["instrumentation_class"], "AddressSanitizer")
82        self.assertEqual(data["stop_type"], "fatal_error")
83
84        # now let's try the SB API
85        process = self.dbg.GetSelectedTarget().process
86        thread = process.GetSelectedThread()
87
88        s = lldb.SBStream()
89        self.assertTrue(thread.GetStopReasonExtendedInfoAsJSON(s))
90        s = s.GetData()
91        data2 = json.loads(s)
92        self.assertEqual(data, data2)
93