xref: /llvm-project/lldb/test/API/commands/expression/call-throws/TestCallThatThrows.py (revision fd35a92300a00edaf56ae94176317390677569a4)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest calling a function that throws an ObjC exception, make sure that it doesn't propagate the exception.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprechtimport lldb
799451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
899451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
999451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1099451b44SJordan Rupprecht
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtclass ExprCommandWithThrowTestCase(TestBase):
1399451b44SJordan Rupprecht    def setUp(self):
1499451b44SJordan Rupprecht        # Call super's setUp().
1599451b44SJordan Rupprecht        TestBase.setUp(self)
1699451b44SJordan Rupprecht
1799451b44SJordan Rupprecht        self.main_source = "call-throws.m"
1899451b44SJordan Rupprecht        self.main_source_spec = lldb.SBFileSpec(self.main_source)
1999451b44SJordan Rupprecht
20a852cf66SMichał Górny    @add_test_categories(["objc"])
2199451b44SJordan Rupprecht    def test(self):
2299451b44SJordan Rupprecht        """Test calling a function that throws and ObjC exception."""
2399451b44SJordan Rupprecht        self.build()
2499451b44SJordan Rupprecht        self.call_function()
2599451b44SJordan Rupprecht
2699451b44SJordan Rupprecht    def check_after_call(self):
2799451b44SJordan Rupprecht        # Check that we are back where we were before:
2899451b44SJordan Rupprecht        frame = self.thread.GetFrameAtIndex(0)
290ed758b2SDave Lee        self.assertEqual(
302238dcc3SJonas Devlieghere            self.orig_frame_pc, frame.GetPC(), "Restored the zeroth frame correctly"
312238dcc3SJonas Devlieghere        )
3299451b44SJordan Rupprecht
3399451b44SJordan Rupprecht    def call_function(self):
3499451b44SJordan Rupprecht        """Test calling function that throws."""
352238dcc3SJonas Devlieghere        (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(
362238dcc3SJonas Devlieghere            self, "I am about to throw.", self.main_source_spec
372238dcc3SJonas Devlieghere        )
3899451b44SJordan Rupprecht
3999451b44SJordan Rupprecht        options = lldb.SBExpressionOptions()
4099451b44SJordan Rupprecht        options.SetUnwindOnError(True)
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        frame = self.thread.GetFrameAtIndex(0)
4399451b44SJordan Rupprecht        # Store away the PC to check that the functions unwind to the right
4499451b44SJordan Rupprecht        # place after calls
4599451b44SJordan Rupprecht        self.orig_frame_pc = frame.GetPC()
4699451b44SJordan Rupprecht
4799451b44SJordan Rupprecht        value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
4899451b44SJordan Rupprecht        self.assertTrue(value.IsValid())
491eeeab82SJordan Rupprecht        self.assertFalse(value.GetError().Success())
5099451b44SJordan Rupprecht
5199451b44SJordan Rupprecht        self.check_after_call()
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht        # Okay, now try with a breakpoint in the called code in the case where
5499451b44SJordan Rupprecht        # we are ignoring breakpoint hits.
5599451b44SJordan Rupprecht        handler_bkpt = target.BreakpointCreateBySourceRegex(
562238dcc3SJonas Devlieghere            "I felt like it", self.main_source_spec
572238dcc3SJonas Devlieghere        )
589c246882SJordan Rupprecht        self.assertGreater(handler_bkpt.GetNumLocations(), 0)
5999451b44SJordan Rupprecht        options.SetIgnoreBreakpoints(True)
6099451b44SJordan Rupprecht        options.SetUnwindOnError(True)
6199451b44SJordan Rupprecht
6299451b44SJordan Rupprecht        value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
6399451b44SJordan Rupprecht
64*fd35a923SEisuke Kawashima        self.assertTrue(value.IsValid() and not value.GetError().Success())
6599451b44SJordan Rupprecht        self.check_after_call()
6699451b44SJordan Rupprecht
6799451b44SJordan Rupprecht        # Now set the ObjC language breakpoint and make sure that doesn't
6899451b44SJordan Rupprecht        # interfere with the call:
6999451b44SJordan Rupprecht        exception_bkpt = target.BreakpointCreateForException(
702238dcc3SJonas Devlieghere            lldb.eLanguageTypeObjC, False, True
712238dcc3SJonas Devlieghere        )
729c246882SJordan Rupprecht        self.assertGreater(exception_bkpt.GetNumLocations(), 0)
7399451b44SJordan Rupprecht
7499451b44SJordan Rupprecht        options.SetIgnoreBreakpoints(True)
7599451b44SJordan Rupprecht        options.SetUnwindOnError(True)
7699451b44SJordan Rupprecht
7799451b44SJordan Rupprecht        value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
7899451b44SJordan Rupprecht
79*fd35a923SEisuke Kawashima        self.assertTrue(value.IsValid() and not value.GetError().Success())
8099451b44SJordan Rupprecht        self.check_after_call()
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht        # Now turn off exception trapping, and call a function that catches the exceptions,
8399451b44SJordan Rupprecht        # and make sure the function actually completes, and we get the right
8499451b44SJordan Rupprecht        # value:
8599451b44SJordan Rupprecht        options.SetTrapExceptions(False)
8699451b44SJordan Rupprecht        value = frame.EvaluateExpression("[my_class iCatchMyself]", options)
8799451b44SJordan Rupprecht        self.assertTrue(value.IsValid())
8835674976SPavel Labath        self.assertSuccess(value.GetError())
8980fcecb1SJonas Devlieghere        self.assertEqual(value.GetValueAsUnsigned(), 57)
9099451b44SJordan Rupprecht        self.check_after_call()
9199451b44SJordan Rupprecht        options.SetTrapExceptions(True)
9299451b44SJordan Rupprecht
9399451b44SJordan Rupprecht        # Now set this unwind on error to false, and make sure that we stop
9499451b44SJordan Rupprecht        # where the exception was thrown
9599451b44SJordan Rupprecht        options.SetUnwindOnError(False)
9699451b44SJordan Rupprecht        value = frame.EvaluateExpression("[my_class callMeIThrow]", options)
9799451b44SJordan Rupprecht
98*fd35a923SEisuke Kawashima        self.assertTrue(value.IsValid() and not value.GetError().Success())
9999451b44SJordan Rupprecht        self.check_after_call()
100