xref: /llvm-project/lldb/test/API/macosx/ignore_exceptions/TestIgnoredExceptions.py (revision 620dc1224ff9e4cb86e6e4d8e7c3941fc921887d)
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