1"""Test that we can unwind out of a SIGABRT handler"""
2
3
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class HandleAbortTestCase(TestBase):
13
14    mydir = TestBase.compute_mydir(__file__)
15
16    NO_DEBUG_INFO_TESTCASE = True
17
18    @skipIfWindows  # signals do not exist on Windows
19    @expectedFailureNetBSD
20    def test_inferior_handle_sigabrt(self):
21        """Inferior calls abort() and handles the resultant SIGABRT.
22           Stopped at a breakpoint in the handler, verify that the backtrace
23           includes the function that called abort()."""
24        self.build()
25        exe = self.getBuildArtifact("a.out")
26
27        # Create a target by the debugger.
28        target = self.dbg.CreateTarget(exe)
29        self.assertTrue(target, VALID_TARGET)
30
31        # launch
32        process = target.LaunchSimple(
33            None, None, self.get_process_working_directory())
34        self.assertTrue(process, PROCESS_IS_VALID)
35        self.assertState(process.GetState(), lldb.eStateStopped)
36        signo = process.GetUnixSignals().GetSignalNumberFromName("SIGABRT")
37
38        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
39        self.assertTrue(
40            thread and thread.IsValid(),
41            "Thread should be stopped due to a signal")
42        self.assertTrue(
43            thread.GetStopReasonDataCount() >= 1,
44            "There should be data in the event.")
45        self.assertEqual(thread.GetStopReasonDataAtIndex(0),
46                         signo, "The stop signal should be SIGABRT")
47
48        # Continue to breakpoint in abort handler
49        bkpt = target.FindBreakpointByID(
50            lldbutil.run_break_set_by_source_regexp(self, "Set a breakpoint here"))
51        threads = lldbutil.continue_to_breakpoint(process, bkpt)
52        self.assertEqual(len(threads), 1, "Expected single thread")
53        thread = threads[0]
54
55        # Expect breakpoint in 'handler'
56        frame = thread.GetFrameAtIndex(0)
57        self.assertEqual(frame.GetDisplayFunctionName(), "handler", "Unexpected break?")
58
59        # Expect that unwinding should find 'abort_caller'
60        foundFoo = False
61        for frame in thread:
62            if frame.GetDisplayFunctionName() == "abort_caller":
63                foundFoo = True
64
65        self.assertTrue(foundFoo, "Unwinding did not find func that called abort")
66
67        # Continue until we exit.
68        process.Continue()
69        self.assertEqual(process.GetState(), lldb.eStateExited)
70        self.assertEqual(process.GetExitStatus(), 0)
71