1fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen"""Test variable with function ptr type and that break on the function works."""
2fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
3fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chenimport os, time
475e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chenimport unittest2
5a1affab962b9f57b64d798ea7fa93dc71d4cc0b1Johnny Chenimport lldb
6d85dae5a089177582aff128c897c78332167fe08Johnny Chenfrom lldbtest import *
7431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
8fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
91c42e8684d26e1473f92c799eeae65a3eec991d6Johnny Chenclass FunctionTypesTestCase(TestBase):
10fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
11de2f1ed2a5dfe306aa6c5d48baf65808608cefb5Johnny Chen    mydir = os.path.join("lang", "c", "function_types")
12fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
13d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
1421b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
15d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen    def test_with_dsym(self):
16d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen        """Test 'callback' has function ptr type, then break on the function."""
17d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen        self.buildDsym()
18d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen        self.function_types()
19d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen
2021b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
21d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen    def test_with_dwarf(self):
22d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen        """Test 'callback' has function ptr type, then break on the function."""
23d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen        self.buildDwarf()
24d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen        self.function_types()
256c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
266c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
2721b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
286c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan    def test_pointers_with_dsym(self):
296c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        """Test that a function pointer to 'printf' works and can be called."""
306c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.buildDsym()
31c01c05c7a8a198761fb917308dd53e6e143384adSean Callanan        self.function_pointers()
32f40b0928e7455c7158ea9aa82d7908cc3fe4d1afEd Maste
33f40b0928e7455c7158ea9aa82d7908cc3fe4d1afEd Maste    @expectedFailureFreeBSD('llvm.org/pr16697') # Expression fails with 'there is no JIT compiled function'
3421b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
356c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan    def test_pointers_with_dwarf(self):
366c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        """Test that a function pointer to 'printf' works and can be called."""
376c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.buildDwarf()
38c01c05c7a8a198761fb917308dd53e6e143384adSean Callanan        self.function_pointers()
39d9ed552026a5d2842d95b2852f33346e867e9799Johnny Chen
40143914211a7e009c90a7d88e7584513d7a4af67fJohnny Chen    def setUp(self):
410910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        # Call super's setUp().
420910eb32b94bd67b0357d34d0951aad197742569Johnny Chen        TestBase.setUp(self)
43143914211a7e009c90a7d88e7584513d7a4af67fJohnny Chen        # Find the line number to break inside main().
44143914211a7e009c90a7d88e7584513d7a4af67fJohnny Chen        self.line = line_number('main.c', '// Set break point at this line.')
45143914211a7e009c90a7d88e7584513d7a4af67fJohnny Chen
466c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan    def runToBreakpoint(self):
47fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        exe = os.path.join(os.getcwd(), "a.out")
484f995f0718299696719089084a622835b6a7b4b8Johnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
496c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
50fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        # Break inside the main.
51431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
526c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
531bb9f9a3917c7ac7228d0a81a0ff8a225165800aJohnny Chen        self.runCmd("run", RUN_SUCCEEDED)
546c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
55fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        # The stop reason of the thread should be breakpoint.
564f995f0718299696719089084a622835b6a7b4b8Johnny Chen        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
576c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan                    substrs = ['stopped',
586c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan                               'stop reason = breakpoint'])
596c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
60fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        # The breakpoint should have a hit count of 1.
6141950cc77813637e6c67b069e4ad2faf8c5f6fa7Caroline Tice        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
626c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan                    substrs = [' resolved, hit count = 1'])
636c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
646c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan    def function_types(self):
656c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        """Test 'callback' has function ptr type, then break on the function."""
666c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
676c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.runToBreakpoint()
68fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
69fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        # Check that the 'callback' variable display properly.
706475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton        self.expect("frame variable --show-types callback", VARIABLES_DISPLAYED_CORRECTLY,
71397636ec9b675f4d917765400419d6b4805bb8a3Johnny Chen            startstr = '(int (*)(const char *)) callback =')
72fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
73fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        # And that we can break on the callback function.
74431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_symbol (self, "string_not_empty", num_expected_locations=1, sym_exact=True)
754f995f0718299696719089084a622835b6a7b4b8Johnny Chen        self.runCmd("continue")
76fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
77fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen        # Check that we do indeed stop on the string_not_empty function.
784f995f0718299696719089084a622835b6a7b4b8Johnny Chen        self.expect("process status", STOPPED_DUE_TO_BREAKPOINT,
7959ea45fc85deacf0b8ca8250f116b7cc7b3691a5Johnny Chen            substrs = ['a.out`string_not_empty',
804f995f0718299696719089084a622835b6a7b4b8Johnny Chen                       'stop reason = breakpoint'])
81fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
826c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan    def function_pointers(self):
836c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        """Test that a function pointer to 'printf' works and can be called."""
846c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
856c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.runToBreakpoint()
866c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
876c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.expect("expr string_not_empty",
886c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan                    substrs = ['(int (*)(const char *)) $0 = ', '(a.out`'])
896c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
90081137057abc6b2c32eb077bde7459f46544f7d8Johnny Chen        if sys.platform.startswith("darwin"):
91081137057abc6b2c32eb077bde7459f46544f7d8Johnny Chen            regexps = ['lib.*\.dylib`printf']
92081137057abc6b2c32eb077bde7459f46544f7d8Johnny Chen        else:
93081137057abc6b2c32eb077bde7459f46544f7d8Johnny Chen            regexps = ['printf']
946c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.expect("expr (int (*)(const char*, ...))printf",
95081137057abc6b2c32eb077bde7459f46544f7d8Johnny Chen                    substrs = ['(int (*)(const char *, ...)) $1 = '],
96081137057abc6b2c32eb077bde7459f46544f7d8Johnny Chen                    patterns = regexps)
976c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan
986c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan        self.expect("expr $1(\"Hello world\\n\")",
996c98ba7d2b7f5e3381cbba5f24e97673c47d109aSean Callanan                    startstr = '(int) $2 = 12')
100fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen
101fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chenif __name__ == '__main__':
10288f8304a5b7864ce3c6966bc0250fa3b7069aef0Johnny Chen    import atexit
103fce55e0f97822a11a92cacb556c38bf69c79af25Johnny Chen    lldb.SBDebugger.Initialize()
10488f8304a5b7864ce3c6966bc0250fa3b7069aef0Johnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
10575e28f942c1b9f9c6d5a0d5f2efd037cbbc9fc74Johnny Chen    unittest2.main()
106