2 Test calling a function that throws an ObjC exception, make sure that it doesn't propagate the exception.
7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbutil
12 class ExprCommandWithThrowTestCase(TestBase
):
14 # Call super's setUp().
17 self
.main_source
= "call-throws.m"
18 self
.main_source_spec
= lldb
.SBFileSpec(self
.main_source
)
20 @add_test_categories(["objc"])
22 """Test calling a function that throws and ObjC exception."""
26 def check_after_call(self
):
27 # Check that we are back where we were before:
28 frame
= self
.thread
.GetFrameAtIndex(0)
30 self
.orig_frame_pc
, frame
.GetPC(), "Restored the zeroth frame correctly"
33 def call_function(self
):
34 """Test calling function that throws."""
35 (target
, process
, self
.thread
, bkpt
) = lldbutil
.run_to_source_breakpoint(
36 self
, "I am about to throw.", self
.main_source_spec
39 options
= lldb
.SBExpressionOptions()
40 options
.SetUnwindOnError(True)
42 frame
= self
.thread
.GetFrameAtIndex(0)
43 # Store away the PC to check that the functions unwind to the right
45 self
.orig_frame_pc
= frame
.GetPC()
47 value
= frame
.EvaluateExpression("[my_class callMeIThrow]", options
)
48 self
.assertTrue(value
.IsValid())
49 self
.assertFalse(value
.GetError().Success())
51 self
.check_after_call()
53 # Okay, now try with a breakpoint in the called code in the case where
54 # we are ignoring breakpoint hits.
55 handler_bkpt
= target
.BreakpointCreateBySourceRegex(
56 "I felt like it", self
.main_source_spec
58 self
.assertGreater(handler_bkpt
.GetNumLocations(), 0)
59 options
.SetIgnoreBreakpoints(True)
60 options
.SetUnwindOnError(True)
62 value
= frame
.EvaluateExpression("[my_class callMeIThrow]", options
)
64 self
.assertTrue(value
.IsValid() and not value
.GetError().Success())
65 self
.check_after_call()
67 # Now set the ObjC language breakpoint and make sure that doesn't
68 # interfere with the call:
69 exception_bkpt
= target
.BreakpointCreateForException(
70 lldb
.eLanguageTypeObjC
, False, True
72 self
.assertGreater(exception_bkpt
.GetNumLocations(), 0)
74 options
.SetIgnoreBreakpoints(True)
75 options
.SetUnwindOnError(True)
77 value
= frame
.EvaluateExpression("[my_class callMeIThrow]", options
)
79 self
.assertTrue(value
.IsValid() and not value
.GetError().Success())
80 self
.check_after_call()
82 # Now turn off exception trapping, and call a function that catches the exceptions,
83 # and make sure the function actually completes, and we get the right
85 options
.SetTrapExceptions(False)
86 value
= frame
.EvaluateExpression("[my_class iCatchMyself]", options
)
87 self
.assertTrue(value
.IsValid())
88 self
.assertSuccess(value
.GetError())
89 self
.assertEqual(value
.GetValueAsUnsigned(), 57)
90 self
.check_after_call()
91 options
.SetTrapExceptions(True)
93 # Now set this unwind on error to false, and make sure that we stop
94 # where the exception was thrown
95 options
.SetUnwindOnError(False)
96 value
= frame
.EvaluateExpression("[my_class callMeIThrow]", options
)
98 self
.assertTrue(value
.IsValid() and not value
.GetError().Success())
99 self
.check_after_call()