1bff4673bSJim Ingham""" 2bff4673bSJim InghamTest that by turning off EXC_BAD_ACCESS catching, we can 3bff4673bSJim Inghamdebug into and out of a signal handler. 4bff4673bSJim Ingham""" 5bff4673bSJim Ingham 6bff4673bSJim Inghamimport lldb 7bff4673bSJim Inghamfrom lldbsuite.test.decorators import * 8bff4673bSJim Inghamimport lldbsuite.test.lldbutil as lldbutil 9bff4673bSJim Inghamfrom lldbsuite.test.lldbtest import * 10bff4673bSJim Ingham 11bff4673bSJim Ingham 122238dcc3SJonas Devlieghereclass TestDarwinSignalHandlers(TestBase): 13bff4673bSJim Ingham NO_DEBUG_INFO_TESTCASE = True 14bff4673bSJim Ingham 15f7bf9d13SJim Ingham @skipIfOutOfTreeDebugserver 16bff4673bSJim Ingham @skipUnlessDarwin 17bff4673bSJim Ingham def test_ignored_thread(self): 18bff4673bSJim Ingham """It isn't possible to convert an EXC_BAD_ACCESS to a signal when 19bff4673bSJim Ingham running under the debugger, which makes debugging SIGBUS handlers 20bff4673bSJim Ingham and so forth difficult. This test sends QIgnoreExceptions and that 21bff4673bSJim Ingham should get us into the signal handler and out again.""" 22bff4673bSJim Ingham self.build() 23bff4673bSJim Ingham self.main_source_file = lldb.SBFileSpec("main.c") 24bff4673bSJim Ingham self.suspended_thread_test() 25bff4673bSJim Ingham 26bff4673bSJim Ingham def suspended_thread_test(self): 27bff4673bSJim Ingham # Make sure that we don't accept bad values: 282238dcc3SJonas Devlieghere self.match( 292238dcc3SJonas Devlieghere "settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_AXESS", 302238dcc3SJonas Devlieghere "EXC_BAD_AXESS", 312238dcc3SJonas Devlieghere error=True, 322238dcc3SJonas Devlieghere ) 33*620dc122SJim Ingham # Make sure that we don't accept exceptions that lldb/debugserver need: 34*620dc122SJim Ingham self.match( 35*620dc122SJim Ingham "settings set platform.plugin.darwin.ignored-exceptions EXC_BREAKPOINT", 36*620dc122SJim Ingham "EXC_BREAKPOINT", 37*620dc122SJim Ingham error=True, 38*620dc122SJim Ingham ) 39*620dc122SJim Ingham # Make sure that we don't accept exceptions that lldb/debugserver need: 40*620dc122SJim Ingham self.match( 41*620dc122SJim Ingham "settings set platform.plugin.darwin.ignored-exceptions EXC_SOFT_SIGNAL", 42*620dc122SJim Ingham "EXC_SOFT_SIGNAL", 43*620dc122SJim Ingham error=True, 44*620dc122SJim Ingham ) 45*620dc122SJim Ingham # Now set ourselves to ignore some exceptions. The test depends on ignoring EXC_BAD_ACCESS, but I passed all the 46*620dc122SJim Ingham # ones we currently accept to make sure they parse: 472238dcc3SJonas Devlieghere self.runCmd( 48*620dc122SJim Ingham "settings set platform.plugin.darwin.ignored-exceptions EXC_BAD_ACCESS|EXC_BAD_INSTRUCTION|EXC_ARITHMETIC|EXC_RESOURCE|EXC_GUARD|EXC_SYSCALL" 492238dcc3SJonas Devlieghere ) 502238dcc3SJonas Devlieghere (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( 512238dcc3SJonas Devlieghere self, "Stop here to get things going", self.main_source_file 522238dcc3SJonas Devlieghere ) 53bff4673bSJim Ingham 542238dcc3SJonas Devlieghere sig_bkpt = target.BreakpointCreateBySourceRegex( 552238dcc3SJonas Devlieghere "stop here in the signal handler", self.main_source_file 562238dcc3SJonas Devlieghere ) 57bff4673bSJim Ingham self.assertEqual(sig_bkpt.GetNumLocations(), 1, "Found sig handler breakpoint") 582238dcc3SJonas Devlieghere return_bkpt = target.BreakpointCreateBySourceRegex( 592238dcc3SJonas Devlieghere "Break here to make sure we got past the signal handler", 602238dcc3SJonas Devlieghere self.main_source_file, 612238dcc3SJonas Devlieghere ) 62bff4673bSJim Ingham self.assertEqual(return_bkpt.GetNumLocations(), 1, "Found return breakpoint") 63bff4673bSJim Ingham # Now continue, and we should stop with a stop reason of SIGBUS: 64bff4673bSJim Ingham process.Continue() 652238dcc3SJonas Devlieghere self.assertState( 662238dcc3SJonas Devlieghere process.state, lldb.eStateStopped, "Stopped after continue to SIGBUS" 672238dcc3SJonas Devlieghere ) 689385a6d6SJim Ingham if thread.stop_reason == lldb.eStopReasonBreakpoint: 699385a6d6SJim Ingham id = thread.GetStopReasonDataAtIndex(0) 709385a6d6SJim Ingham name = thread.frame[0].name 712238dcc3SJonas Devlieghere self.fail( 722238dcc3SJonas Devlieghere "Hit breakpoint {0} in '{1}' rather than getting a SIGBUS".format( 732238dcc3SJonas Devlieghere id, name 742238dcc3SJonas Devlieghere ) 752238dcc3SJonas Devlieghere ) 769385a6d6SJim Ingham 770f821339SJonas Devlieghere self.assertStopReason(thread.stop_reason, lldb.eStopReasonSignal) 78bff4673bSJim Ingham self.assertEqual(thread.GetStopReasonDataAtIndex(0), 10, "Got a SIGBUS") 79bff4673bSJim Ingham 80bff4673bSJim Ingham # Now when we continue, we'll find our way into the signal handler: 81bff4673bSJim Ingham threads = lldbutil.continue_to_breakpoint(process, sig_bkpt) 82bff4673bSJim Ingham self.assertEqual(len(threads), 1, "Stopped at sig breakpoint") 83bff4673bSJim Ingham 84bff4673bSJim Ingham threads = lldbutil.continue_to_breakpoint(process, return_bkpt) 85bff4673bSJim Ingham self.assertEqual(len(threads), 1, "Stopped at return breakpoint") 86bff4673bSJim Ingham 87bff4673bSJim Ingham # Make sure we really changed the value: 88bff4673bSJim Ingham 89bff4673bSJim Ingham process.Continue() 90e06a88cbSJonas Devlieghere self.assertState(process.state, lldb.eStateExited, "Process exited") 91bff4673bSJim Ingham self.assertEqual(process.exit_state, 20, "Got the right exit status") 92