2 Test SB API support for identifying artificial (tail call) frames.
6 import lldbsuite.test.lldbutil as lldbutil
7 from lldbsuite.test.decorators import *
8 from lldbsuite.test.lldbtest import *
10 class TestArtificialFrameThreadStepOut1(TestBase):
11 mydir = TestBase.compute_mydir(__file__)
13 # If your test case doesn't stress debug info, the
14 # set this to true. That way it won't be run once for
15 # each debug info format.
16 NO_DEBUG_INFO_TESTCASE = True
18 def prepare_thread(self):
19 exe = self.getBuildArtifact("a.out")
21 # Create a target by the debugger.
22 target = self.dbg.CreateTarget(exe)
23 self.assertTrue(target, VALID_TARGET)
25 breakpoint = target.BreakpointCreateBySourceRegex("break here",
26 lldb.SBFileSpec("main.cpp"))
27 self.assertTrue(breakpoint and
28 breakpoint.GetNumLocations() == 1,
31 error = lldb.SBError()
32 launch_info = lldb.SBLaunchInfo(None)
33 process = target.Launch(launch_info, error)
34 self.assertTrue(process, PROCESS_IS_VALID)
36 # Did we hit our breakpoint?
37 threads = lldbutil.get_threads_stopped_at_breakpoint(process,
41 "There should be a thread stopped at our breakpoint")
43 self.assertEqual(breakpoint.GetHitCount(), 1)
47 # Here's what we expect to see in the backtrace:
48 # frame #0: ... a.out`sink() at main.cpp:13:4 [opt]
49 # frame #1: ... a.out`func3() at main.cpp:14:1 [opt] [artificial]
50 # frame #2: ... a.out`func2() at main.cpp:18:62 [opt]
51 # frame #3: ... a.out`func1() at main.cpp:18:85 [opt] [artificial]
52 # frame #4: ... a.out`main at main.cpp:23:3 [opt]
55 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr26265")
56 def test_stepping_out_past_artificial_frame(self):
58 thread = self.prepare_thread()
60 # Frame #0's ancestor is artificial. Stepping out should move to
61 # frame #2, because we behave as-if artificial frames were not present.
63 frame2 = thread.GetSelectedFrame()
64 self.assertEqual(frame2.GetDisplayFunctionName(), "func2()")
65 self.assertFalse(frame2.IsArtificial())
67 # Ditto: stepping out of frame #2 should move to frame #4.
69 frame4 = thread.GetSelectedFrame()
70 self.assertEqual(frame4.GetDisplayFunctionName(), "main")
71 self.assertFalse(frame2.IsArtificial())
73 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr26265")
74 def test_return_past_artificial_frame(self):
76 thread = self.prepare_thread()
78 value = lldb.SBValue()
80 # Frame #0's ancestor is artificial. Returning from frame #0 should move
82 thread.ReturnFromFrame(thread.GetSelectedFrame(), value)
83 frame2 = thread.GetSelectedFrame()
84 self.assertEqual(frame2.GetDisplayFunctionName(), "func2()")
85 self.assertFalse(frame2.IsArtificial())
87 # Ditto: stepping out of frame #2 should move to frame #4.
88 thread.ReturnFromFrame(thread.GetSelectedFrame(), value)
89 frame4 = thread.GetSelectedFrame()
90 self.assertEqual(frame4.GetDisplayFunctionName(), "main")
91 self.assertFalse(frame2.IsArtificial())