1 """ 2 Test lldb exception breakpoint command for CPP. 3 """ 4 5 import os, time 6 import unittest2 7 import lldb 8 import lldbutil 9 from lldbtest import * 10 11 class CPPBreakpointTestCase(TestBase): 12 13 mydir = os.path.join("lang", "cpp", "exceptions") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @dsym_test 17 def test_with_dsym(self): 18 """Test lldb exception breakpoint command for CPP.""" 19 self.buildDsym() 20 self.cpp_exceptions() 21 22 @dwarf_test 23 def test_with_dwarf(self): 24 """Test lldb exception breakpoint command for CPP.""" 25 self.buildDwarf() 26 self.cpp_exceptions() 27 28 def setUp(self): 29 # Call super's setUp(). 30 TestBase.setUp(self) 31 self.source = 'exceptions.cpp' 32 self.catch_line = line_number(self.source, '// This is the line you should stop at for catch') 33 34 def cpp_exceptions (self): 35 """Test lldb exception breakpoint command for CPP.""" 36 exe = os.path.join(os.getcwd(), "a.out") 37 38 # Create a target from the debugger. 39 40 target = self.dbg.CreateTarget (exe) 41 self.assertTrue(target, VALID_TARGET) 42 43 exception_bkpt = target.BreakpointCreateForException (lldb.eLanguageTypeC_plus_plus, True, True) 44 self.assertTrue (exception_bkpt, "Made an exception breakpoint") 45 46 # Now run, and make sure we hit our breakpoint: 47 process = target.LaunchSimple (None, None, os.getcwd()) 48 self.assertTrue (process, "Got a valid process") 49 50 stopped_threads = [] 51 stopped_threads = lldbutil.get_threads_stopped_at_breakpoint (process, exception_bkpt) 52 self.assertTrue (len(stopped_threads) == 1, "Stopped at our exception breakpoint.") 53 thread = stopped_threads[0] 54 # Make sure our throw function is still above us on the stack: 55 56 frame_functions = lldbutil.get_function_names(thread) 57 self.assertTrue (frame_functions.count ("throws_exception_on_even(int)") == 1, "Our throw function is still on the stack.") 58 59 # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint. 60 # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw. 61 # so loop till we don't see the throws function on the stack. We should stop one more time for our exception breakpoint 62 # and that should be the catch... 63 64 while frame_functions.count ("throws_exception_on_even(int)") == 1: 65 stopped_threads = lldbutil.continue_to_breakpoint (process, exception_bkpt) 66 self.assertTrue (len(stopped_threads) == 1) 67 68 thread = stopped_threads[0] 69 frame_functions = lldbutil.get_function_names(thread) 70 71 self.assertTrue (frame_functions.count ("throws_exception_on_even(int)") == 0, "At catch our throw function is off the stack") 72 self.assertTrue (frame_functions.count ("intervening_function(int)") == 0, "At catch our intervening function is off the stack") 73 self.assertTrue (frame_functions.count ("catches_exception(int)") == 1, "At catch our catch function is on the stack") 74 75 76 77 if __name__ == '__main__': 78 import atexit 79 lldb.SBDebugger.Initialize() 80 atexit.register(lambda: lldb.SBDebugger.Terminate()) 81 unittest2.main() 82