diff options
author | Jim Ingham <jingham@apple.com> | 2013-05-16 21:52:36 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2013-05-16 21:52:36 +0000 |
commit | 641a67ce26d8cd646a90e5ad07a88b42bffea3f1 (patch) | |
tree | 659f41030303837622176b9538fa271001326b16 | |
parent | 065d720c314702a9253eb243b38e72cb538c31c7 (diff) | |
download | bcm5719-llvm-641a67ce26d8cd646a90e5ad07a88b42bffea3f1.tar.gz bcm5719-llvm-641a67ce26d8cd646a90e5ad07a88b42bffea3f1.zip |
Handle the case where there is a user breakpoint set at the location of one of our
function call exception catching breakpoints. We need to force ourselves to stop in
that case.
<rdar://problem/13903801>
llvm-svn: 182056
-rw-r--r-- | lldb/source/Target/ThreadPlanCallFunction.cpp | 8 | ||||
-rw-r--r-- | lldb/test/expression_command/call-throws/TestCallThatThrows.py | 22 |
2 files changed, 25 insertions, 5 deletions
diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 0a77d0d1537..2b5af7cebeb 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -591,7 +591,15 @@ ThreadPlanCallFunction::BreakpointsExplainStop() ||(m_objc_language_runtime && m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))) { + Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete."); + SetPlanComplete(false); + + // If the user has set the ObjC language breakpoint, it would normally get priority over our internal + // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here. + stop_info_sp->OverrideShouldStop (true); return true; } diff --git a/lldb/test/expression_command/call-throws/TestCallThatThrows.py b/lldb/test/expression_command/call-throws/TestCallThatThrows.py index 596c3ef8e5f..8a849b322b9 100644 --- a/lldb/test/expression_command/call-throws/TestCallThatThrows.py +++ b/lldb/test/expression_command/call-throws/TestCallThatThrows.py @@ -1,5 +1,5 @@ """ -Test calling a function that hits a signal set to auto-restart, make sure the call completes. +Test calling a function that throws an ObjC exception, make sure that it doesn't propagate the exception. """ import unittest2 @@ -7,7 +7,7 @@ import lldb import lldbutil from lldbtest import * -class ExprCommandWithTimeoutsTestCase(TestBase): +class ExprCommandWithThrowTestCase(TestBase): mydir = os.path.join("expression_command", "call-throws") @@ -22,14 +22,14 @@ class ExprCommandWithTimeoutsTestCase(TestBase): @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @dsym_test def test_with_dsym(self): - """Test calling std::String member function.""" + """Test calling a function that throws and ObjC exception.""" self.buildDsym() self.call_function() @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin due to ObjC test case") @dwarf_test def test_with_dwarf(self): - """Test calling std::String member function.""" + """Test calling a function that throws and ObjC exception.""" self.buildDwarf() self.call_function() @@ -40,7 +40,7 @@ class ExprCommandWithTimeoutsTestCase(TestBase): def call_function(self): - """Test calling function with timeout.""" + """Test calling function that throws.""" exe_name = "a.out" exe = os.path.join(os.getcwd(), exe_name) @@ -86,6 +86,18 @@ class ExprCommandWithTimeoutsTestCase(TestBase): self.assertTrue (value.IsValid() and value.GetError().Success() == False) self.check_after_call() + # Now set the ObjC language breakpoint and make sure that doesn't interfere with the call: + exception_bkpt = target.BreakpointCreateForException (lldb.eLanguageTypeObjC, False, True) + self.assertTrue(exception_bkpt.GetNumLocations() > 0) + + options.SetIgnoreBreakpoints(True) + options.SetUnwindOnError(True) + + value = frame.EvaluateExpression ("[my_class callMeIThrow]", options) + + self.assertTrue (value.IsValid() and value.GetError().Success() == False) + self.check_after_call() + # Now set this unwind on error to false, and make sure that we stop where the exception was thrown options.SetUnwindOnError(False) value = frame.EvaluateExpression ("[my_class callMeIThrow]", options) |