diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py')
-rw-r--r-- | lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py | 108 |
1 files changed, 96 insertions, 12 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py b/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py index 6959f2ef75d..b5511549fd5 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py +++ b/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py @@ -17,13 +17,14 @@ class ObjCExceptionsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) @skipUnlessDarwin - def test_objc_exceptions_1(self): + def test_objc_exceptions_at_throw(self): self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) - lldbutil.run_to_name_breakpoint(self, "objc_exception_throw") + launch_info = lldb.SBLaunchInfo(["a.out", "0"]) + lldbutil.run_to_name_breakpoint(self, "objc_exception_throw", launch_info=launch_info) self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) @@ -33,7 +34,7 @@ class ObjCExceptionsTestCase(TestBase): 'name: "ThrownException" - reason: "SomeReason"', ]) - lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.m")) + lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.mm"), launch_info=launch_info) self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) @@ -42,19 +43,23 @@ class ObjCExceptionsTestCase(TestBase): thread = target.GetProcess().GetSelectedThread() frame = thread.GetSelectedFrame() + # No exception being currently thrown/caught at this point + self.assertFalse(thread.GetCurrentException().IsValid()) + self.assertFalse(thread.GetCurrentExceptionBacktrace().IsValid()) + self.expect( 'frame variable e1', substrs=[ '(NSException *) e1 = ', - 'name: @"ExceptionName" - reason: @"SomeReason"' + 'name: "ExceptionName" - reason: "SomeReason"' ]) self.expect( 'frame variable --dynamic-type no-run-target *e1', substrs=[ '(NSException) *e1 = ', - 'name = ', '@"ExceptionName"', - 'reason = ', '@"SomeReason"', + 'name = ', '"ExceptionName"', + 'reason = ', '"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', 'nil', ]) @@ -62,7 +67,7 @@ class ObjCExceptionsTestCase(TestBase): e1 = frame.FindVariable("e1") self.assertTrue(e1) self.assertEqual(e1.type.name, "NSException *") - self.assertEqual(e1.GetSummary(), 'name: @"ExceptionName" - reason: @"SomeReason"') + self.assertEqual(e1.GetSummary(), 'name: "ExceptionName" - reason: "SomeReason"') self.assertEqual(e1.GetChildMemberWithName("name").description, "ExceptionName") self.assertEqual(e1.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e1.GetChildMemberWithName("userInfo").dynamic @@ -75,15 +80,15 @@ class ObjCExceptionsTestCase(TestBase): 'frame variable e2', substrs=[ '(NSException *) e2 = ', - 'name: @"ThrownException" - reason: @"SomeReason"' + 'name: "ThrownException" - reason: "SomeReason"' ]) self.expect( 'frame variable --dynamic-type no-run-target *e2', substrs=[ '(NSException) *e2 = ', - 'name = ', '@"ThrownException"', - 'reason = ', '@"SomeReason"', + 'name = ', '"ThrownException"', + 'reason = ', '"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', ]) @@ -91,7 +96,7 @@ class ObjCExceptionsTestCase(TestBase): e2 = frame.FindVariable("e2") self.assertTrue(e2) self.assertEqual(e2.type.name, "NSException *") - self.assertEqual(e2.GetSummary(), 'name: @"ThrownException" - reason: @"SomeReason"') + self.assertEqual(e2.GetSummary(), 'name: "ThrownException" - reason: "SomeReason"') self.assertEqual(e2.GetChildMemberWithName("name").description, "ThrownException") self.assertEqual(e2.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e2.GetChildMemberWithName("userInfo").dynamic @@ -106,5 +111,84 @@ class ObjCExceptionsTestCase(TestBase): pcs = [i.unsigned for i in children] names = [target.ResolveSymbolContextForAddress(lldb.SBAddress(pc, target), lldb.eSymbolContextSymbol).GetSymbol().name for pc in pcs] - for n in ["objc_exception_throw", "foo", "main"]: + for n in ["objc_exception_throw", "foo(int)", "main"]: self.assertTrue(n in names, "%s is in the exception backtrace (%s)" % (n, names)) + + @skipUnlessDarwin + def test_objc_exceptions_at_abort(self): + self.build() + + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + self.runCmd("run 0") + + # We should be stopped at pthread_kill because of an unhandled exception + self.expect("thread list", + substrs=['stopped', 'stop reason = signal SIGABRT']) + + self.expect('thread exception', substrs=[ + '(NSException *) exception = ', + 'name: "ThrownException" - reason: "SomeReason"', + 'libobjc.A.dylib`objc_exception_throw', + 'a.out`foo', 'at main.mm:25', + 'a.out`rethrow', 'at main.mm:36', + 'a.out`main', + ]) + + process = self.dbg.GetSelectedTarget().process + thread = process.GetSelectedThread() + + # There is an exception being currently processed at this point + self.assertTrue(thread.GetCurrentException().IsValid()) + self.assertTrue(thread.GetCurrentExceptionBacktrace().IsValid()) + + history_thread = thread.GetCurrentExceptionBacktrace() + self.assertGreaterEqual(history_thread.num_frames, 4) + for n in ["objc_exception_throw", "foo(int)", "rethrow(int)", "main"]: + self.assertEqual(len([f for f in history_thread.frames if f.GetFunctionName() == n]), 1) + + self.runCmd("kill") + + self.runCmd("run 1") + # We should be stopped at pthread_kill because of an unhandled exception + self.expect("thread list", + substrs=['stopped', 'stop reason = signal SIGABRT']) + + self.expect('thread exception', substrs=[ + '(MyCustomException *) exception = ', + 'libobjc.A.dylib`objc_exception_throw', + 'a.out`foo', 'at main.mm:27', + 'a.out`rethrow', 'at main.mm:36', + 'a.out`main', + ]) + + process = self.dbg.GetSelectedTarget().process + thread = process.GetSelectedThread() + + history_thread = thread.GetCurrentExceptionBacktrace() + self.assertGreaterEqual(history_thread.num_frames, 4) + for n in ["objc_exception_throw", "foo(int)", "rethrow(int)", "main"]: + self.assertEqual(len([f for f in history_thread.frames if f.GetFunctionName() == n]), 1) + + @skipUnlessDarwin + def test_cxx_exceptions_at_abort(self): + self.build() + + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + self.runCmd("run 2") + + # We should be stopped at pthread_kill because of an unhandled exception + self.expect("thread list", + substrs=['stopped', 'stop reason = signal SIGABRT']) + + self.expect('thread exception', substrs=[]) + + process = self.dbg.GetSelectedTarget().process + thread = process.GetSelectedThread() + + # C++ exceptions are not exposed in the API (yet). + self.assertFalse(thread.GetCurrentException().IsValid()) + self.assertFalse(thread.GetCurrentExceptionBacktrace().IsValid()) |