1""" 2Test that the built in ObjC exception throw recognizer works 3""" 4 5import lldb 6from lldbsuite.test.decorators import * 7import lldbsuite.test.lldbutil as lldbutil 8from lldbsuite.test.lldbtest import * 9 10 11class TestObjCRecognizer(TestBase): 12 NO_DEBUG_INFO_TESTCASE = True 13 14 @skipUnlessDarwin 15 def test_exception_recognizer_sub_class(self): 16 """There can be many tests in a test case - describe this test here.""" 17 self.build() 18 self.main_source_file = lldb.SBFileSpec("main.m") 19 self.objc_recognizer_test(True) 20 21 @skipUnlessDarwin 22 def test_exception_recognizer_plain(self): 23 """There can be many tests in a test case - describe this test here.""" 24 self.build() 25 self.main_source_file = lldb.SBFileSpec("main.m") 26 self.objc_recognizer_test(False) 27 28 def objc_recognizer_test(self, sub_class): 29 """Make sure we stop at the exception and get all the fields out of the recognizer. 30 If sub_class is True, we make a subclass of NSException and throw that.""" 31 if sub_class: 32 bkpt_string = "Set a breakpoint here for MyException" 33 else: 34 bkpt_string = "Set a breakpoint here for plain exception" 35 36 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( 37 self, bkpt_string, self.main_source_file 38 ) 39 40 # Now turn on the ObjC Exception breakpoint and continue to hit it: 41 exception_bkpt = target.BreakpointCreateForException( 42 lldb.eLanguageTypeObjC, False, True 43 ) 44 self.assertGreater( 45 exception_bkpt.GetNumLocations(), 0, "Got some exception locations" 46 ) 47 48 threads = lldbutil.continue_to_breakpoint(process, exception_bkpt) 49 self.assertEqual(len(threads), 1, "One thread hit exception breakpoint") 50 frame = threads[0].frame[0] 51 52 var_opts = lldb.SBVariablesOptions() 53 var_opts.SetIncludeRecognizedArguments(True) 54 var_opts.SetUseDynamic(True) 55 vars = frame.GetVariables(var_opts) 56 self.assertEqual(len(vars), 1, "Got the synthetic argument") 57 self.assertTrue(vars[0].IsValid(), "Got a valid Exception variable") 58 59 # This will be a pointer 60 61 ns_exception_children = [ 62 ValueCheck(type="NSObject"), 63 ValueCheck(name="name", summary='"NSException"'), 64 ValueCheck(name="reason", summary='"Simple Reason"'), 65 ValueCheck(name="userInfo"), 66 ValueCheck(name="reserved"), 67 ] 68 ns_exception = ValueCheck(type="NSException", children=ns_exception_children) 69 if not sub_class: 70 simple_check = ValueCheck(name="exception", dereference=ns_exception) 71 simple_check.check_value(self, vars[0], "Simple exception is right") 72 else: 73 my_exception_children = [ 74 ns_exception, 75 ValueCheck(name="extra_info", type="int", value="100"), 76 ] 77 my_exception = ValueCheck( 78 type="MyException", children=my_exception_children 79 ) 80 sub_check = ValueCheck( 81 name="exception", type="MyException *", dereference=my_exception 82 ) 83 sub_check.check_value(self, vars[0], "Subclass exception is right") 84