1d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen"""
2d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny ChenTest thread stepping features in combination with frame select.
3d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen"""
4d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
5d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenimport os, time
6d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenimport re
7d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenimport unittest2
8d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenimport lldb, lldbutil
9d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenfrom lldbtest import *
10431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
11d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
12d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenclass ThreadSteppingTestCase(TestBase):
13d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
14b26db29eebfbc2dc88776afa738a9b6a8fcc8f75Johnny Chen    mydir = os.path.join("lang", "c", "stepping")
15d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
16d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
1721b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
18d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    def test_step_out_with_dsym_and_run_command(self):
19d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        """Exercise thread step-out and frame select followed by thread step-out."""
20d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.buildDwarf()
21d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.thread_step_out()
22d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
2321b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
24d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    def test_step_out_with_dwarf_and_run_command(self):
25d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        """Exercise thread step-out and frame select followed by thread step-out."""
26d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.buildDwarf()
27d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.thread_step_out()
28d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
29d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    def setUp(self):
30d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # Call super's setUp().
31d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        TestBase.setUp(self)
32d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # Find the line number to of function 'c'.
33d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.line1 = line_number('main.c', '// Find the line number of function "c" here.')
34d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.line2 = line_number('main.c', '// frame select 2, thread step-out while stopped at "c(1)"')
35d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.line3 = line_number('main.c', '// thread step-out while stopped at "c(2)"')
36d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.line4 = line_number('main.c', '// frame select 1, thread step-out while stopped at "c(3)"')
37d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
38d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    def thread_step_out(self):
39d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        """Exercise thread step-out and frame select followed by thread step-out."""
40d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        exe = os.path.join(os.getcwd(), "a.out")
41d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
42d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
43d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # Create a breakpoint inside function 'c'.
44431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line1, num_expected_locations=1, loc_exact=True)
45d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
46d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # Now run the program.
47d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("run", RUN_SUCCEEDED)
48d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
49d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # The process should be stopped at this point.
50d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("process status", PROCESS_STOPPED,
51d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ['Process .* stopped'])
52d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
53d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # The frame #0 should correspond to main.c:32, the executable statement
54d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # in function name 'c'.  And frame #3 should point to main.c:37.
55d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
56d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            substrs = ["stop reason = breakpoint"],
57d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ["frame #0.*main.c:%d" % self.line1,
58d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen                        "frame #3.*main.c:%d" % self.line2])
59d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
60d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # We want to move the pc to frame #3.  This can be accomplished by
61d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # 'frame select 2', followed by 'thread step-out'.
62d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("frame select 2")
63d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("thread step-out")
64d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("thread backtrace", STEP_OUT_SUCCEEDED,
65d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            substrs = ["stop reason = step out"],
66d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ["frame #0.*main.c:%d" % self.line2])
67d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
68d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # Let's move on to a single step-out case.
69d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("process continue")
70d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
71d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # The process should be stopped at this point.
72d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("process status", PROCESS_STOPPED,
73d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ['Process .* stopped'])
74d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("thread step-out")
75d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("thread backtrace", STEP_OUT_SUCCEEDED,
76d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            substrs = ["stop reason = step out"],
77d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ["frame #0.*main.c:%d" % self.line3])
78d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
79d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # Do another frame selct, followed by thread step-out.
80d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("process continue")
81d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
82d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        # The process should be stopped at this point.
83d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("process status", PROCESS_STOPPED,
84d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ['Process .* stopped'])
85d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("frame select 1")
86d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.runCmd("thread step-out")
87d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen        self.expect("thread backtrace", STEP_OUT_SUCCEEDED,
88d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            substrs = ["stop reason = step out"],
89d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen            patterns = ["frame #0.*main.c:%d" % self.line4])
90d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
91d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen
92d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chenif __name__ == '__main__':
93d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    import atexit
94d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    lldb.SBDebugger.Initialize()
95d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    atexit.register(lambda: lldb.SBDebugger.Terminate())
96d6228a99d1fff462a2ed861b41da0dae08d35acaJohnny Chen    unittest2.main()
97