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