[Lldb-commits] [lldb] r175127 - Add a test for handling a function call that throws an exception, and make it work.
Jim Ingham
jingham at apple.com
Wed Feb 13 19:05:43 PST 2013
Author: jingham
Date: Wed Feb 13 21:05:42 2013
New Revision: 175127
URL: http://llvm.org/viewvc/llvm-project?rev=175127&view=rev
Log:
Add a test for handling a function call that throws an exception, and make it work.
<rdar://problem/13183944>
Added:
lldb/trunk/test/expression_command/call-throws/
lldb/trunk/test/expression_command/call-throws/Makefile
lldb/trunk/test/expression_command/call-throws/TestCallThatThrows.py
lldb/trunk/test/expression_command/call-throws/call-throws.m
Modified:
lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
lldb/trunk/source/Target/StopInfo.cpp
lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=175127&r1=175126&r2=175127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Wed Feb 13 21:05:42 2013
@@ -418,7 +418,8 @@ ItaniumABILanguageRuntime::SetExceptionB
SearchFilterSP filter_sp = target.GetSearchFilterForModule(NULL);
m_cxx_exception_bp_sp = target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
- m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
+ if (m_cxx_exception_bp_sp)
+ m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
}
else
m_cxx_exception_bp_sp->SetEnabled (true);
Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=175127&r1=175126&r2=175127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Wed Feb 13 21:05:42 2013
@@ -333,11 +333,15 @@ AppleObjCRuntime::SetExceptionBreakpoint
const bool is_internal = true;
if (!m_objc_exception_bp_sp)
+ {
m_objc_exception_bp_sp = LanguageRuntime::CreateExceptionBreakpoint (m_process->GetTarget(),
GetLanguageType(),
catch_bp,
throw_bp,
is_internal);
+ if (m_objc_exception_bp_sp)
+ m_objc_exception_bp_sp->SetBreakpointKind("ObjC exception");
+ }
else
m_objc_exception_bp_sp->SetEnabled(true);
}
Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=175127&r1=175126&r2=175127&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Wed Feb 13 21:05:42 2013
@@ -233,10 +233,29 @@ public:
StreamString strm;
if (m_break_id != LLDB_INVALID_BREAK_ID)
{
- if (m_was_one_shot)
- strm.Printf ("one-shot breakpoint %d", m_break_id);
+ BreakpointSP break_sp = m_thread.GetProcess()->GetTarget().GetBreakpointByID(m_break_id);
+ if (break_sp)
+ {
+ if (break_sp->IsInternal())
+ {
+ const char *kind = break_sp->GetBreakpointKind();
+ if (kind)
+ strm.Printf ("internal %s breakpoint(%d).", kind, m_break_id);
+ else
+ strm.Printf ("internal breakpoint(%d).", m_break_id);
+ }
+ else
+ {
+ strm.Printf ("breakpoint %d.", m_break_id);
+ }
+ }
else
- strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
+ {
+ if (m_was_one_shot)
+ strm.Printf ("one-shot breakpoint %d", m_break_id);
+ else
+ strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
+ }
}
else if (m_address == LLDB_INVALID_ADDRESS)
strm.Printf("breakpoint site %" PRIi64 " which has been deleted - unknown address", m_value);
Modified: lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallFunction.cpp?rev=175127&r1=175126&r2=175127&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Wed Feb 13 21:05:42 2013
@@ -579,12 +579,6 @@ ThreadPlanCallFunction::BreakpointsExpla
return true;
}
- // Finally, if the process is set to ignore breakpoints in function calls,
- // then we explain all breakpoint stops.
-
- if (m_ignore_breakpoints)
- return true;
-
return false;
}
Added: lldb/trunk/test/expression_command/call-throws/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/call-throws/Makefile?rev=175127&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/call-throws/Makefile (added)
+++ lldb/trunk/test/expression_command/call-throws/Makefile Wed Feb 13 21:05:42 2013
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+OBJC_SOURCES := call-throws.m
+
+include $(LEVEL)/Makefile.rules
+LDFLAGS += -framework Foundation
Added: lldb/trunk/test/expression_command/call-throws/TestCallThatThrows.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/call-throws/TestCallThatThrows.py?rev=175127&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/call-throws/TestCallThatThrows.py (added)
+++ lldb/trunk/test/expression_command/call-throws/TestCallThatThrows.py Wed Feb 13 21:05:42 2013
@@ -0,0 +1,100 @@
+"""
+Test calling a function that hits a signal set to auto-restart, make sure the call completes.
+"""
+
+import unittest2
+import lldb
+import lldbutil
+from lldbtest import *
+
+class ExprCommandWithTimeoutsTestCase(TestBase):
+
+ mydir = os.path.join("expression_command", "call-throws")
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ self.main_source = "call-throws.m"
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test calling std::String member function."""
+ self.buildDsym()
+ self.call_function()
+
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test calling std::String member function."""
+ self.buildDwarf()
+ self.call_function()
+
+ def check_after_call (self):
+ # Check that we are back where we were before:
+ frame = self.thread.GetFrameAtIndex(0)
+ self.assertTrue (self.orig_frame_pc == frame.GetPC(), "Restored the zeroth frame correctly")
+
+
+ def call_function(self):
+ """Test calling function with timeout."""
+ exe_name = "a.out"
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateBySourceRegex('I am about to throw.',self.main_source_spec)
+ self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be at our breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
+
+ self.assertTrue(len(threads) == 1)
+ self.thread = threads[0]
+
+ options = lldb.SBExpressionOptions()
+ options.SetUnwindOnError(True)
+
+ frame = self.thread.GetFrameAtIndex(0)
+ # Store away the PC to check that the functions unwind to the right place after calls
+ self.orig_frame_pc = frame.GetPC()
+
+ value = frame.EvaluateExpression ("[my_class callMeIThrow]", options)
+ self.assertTrue (value.IsValid())
+ self.assertTrue (value.GetError().Success() == False)
+
+ self.check_after_call()
+
+ # Okay, now try with a breakpoint in the called code in the case where
+ # we are ignoring breakpoint hits.
+ handler_bkpt = target.BreakpointCreateBySourceRegex("I felt like it", self.main_source_spec)
+ self.assertTrue (handler_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)
+
+
+ self.assertTrue (value.IsValid() and value.GetError().Success() == False)
+ self.check_after_call()
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/expression_command/call-throws/call-throws.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/call-throws/call-throws.m?rev=175127&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/call-throws/call-throws.m (added)
+++ lldb/trunk/test/expression_command/call-throws/call-throws.m Wed Feb 13 21:05:42 2013
@@ -0,0 +1,32 @@
+#import <Foundation/Foundation.h>
+
+ at interface MyClass : NSObject
+{
+}
+- (int) callMeIThrow;
+ at end
+
+ at implementation MyClass
+- (int) callMeIThrow
+{
+ NSException *e = [NSException
+ exceptionWithName:@"JustForTheHeckOfItException"
+ reason:@"I felt like it"
+ userInfo:nil];
+ @throw e;
+ return 56;
+}
+ at end
+
+int
+main ()
+{
+ int return_value;
+ MyClass *my_class = [[MyClass alloc] init];
+
+ NSLog (@"I am about to throw.");
+
+ return_value = [my_class callMeIThrow];
+
+ return return_value;
+}
More information about the lldb-commits
mailing list