1"""
2Test lldb exception breakpoint command for CPP.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class CPPBreakpointTestCase(TestBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16
17    def setUp(self):
18        # Call super's setUp().
19        TestBase.setUp(self)
20        self.source = 'exceptions.cpp'
21        self.catch_line = line_number(
22            self.source, '// This is the line you should stop at for catch')
23
24    @expectedFailureAll(
25        oslist=["windows"],
26        bugnumber="llvm.org/pr24538, clang-cl does not support throw or catch")
27    @expectedFailureNetBSD
28    def test(self):
29        """Test lldb exception breakpoint command for CPP."""
30        self.build()
31        exe = self.getBuildArtifact("a.out")
32
33        # Create a target from the debugger.
34
35        target = self.dbg.CreateTarget(exe)
36        self.assertTrue(target, VALID_TARGET)
37
38        exception_bkpt = target.BreakpointCreateForException(
39            lldb.eLanguageTypeC_plus_plus, True, True)
40        self.assertTrue(exception_bkpt, "Made an exception breakpoint")
41
42        # Now run, and make sure we hit our breakpoint:
43        process = target.LaunchSimple(
44            None, None, self.get_process_working_directory())
45        self.assertTrue(process, "Got a valid process")
46
47        stopped_threads = []
48        stopped_threads = lldbutil.get_threads_stopped_at_breakpoint(
49            process, exception_bkpt)
50        self.assertTrue(
51            len(stopped_threads) == 1,
52            "Stopped at our exception breakpoint.")
53        thread = stopped_threads[0]
54        # Make sure our throw function is still above us on the stack:
55
56        frame_functions = lldbutil.get_function_names(thread)
57        self.assertTrue(
58            frame_functions.count("throws_exception_on_even(int)") == 1,
59            "Our throw function is still on the stack.")
60
61        # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint.
62        # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw.
63        # so loop till we don't see the throws function on the stack.  We should stop one more time for our exception breakpoint
64        # and that should be the catch...
65
66        while frame_functions.count("throws_exception_on_even(int)") == 1:
67            stopped_threads = lldbutil.continue_to_breakpoint(
68                process, exception_bkpt)
69            self.assertEquals(len(stopped_threads), 1)
70
71            thread = stopped_threads[0]
72            frame_functions = lldbutil.get_function_names(thread)
73
74        self.assertTrue(
75            frame_functions.count("throws_exception_on_even(int)") == 0,
76            "At catch our throw function is off the stack")
77        self.assertTrue(
78            frame_functions.count("intervening_function(int)") == 0,
79            "At catch our intervening function is off the stack")
80        self.assertTrue(
81            frame_functions.count("catches_exception(int)") == 1,
82            "At catch our catch function is on the stack")
83