xref: /llvm-project/lldb/test/API/tools/lldb-dap/stackTrace/TestDAP_stackTrace.py (revision 5b4100cc354148a1140546e7f5ac2bf380bc5eff)
101263c6cSJonas Devlieghere"""
2*5b4100ccSJohn HarrisonTest lldb-dap stackTrace request
301263c6cSJonas Devlieghere"""
401263c6cSJonas Devlieghere
501263c6cSJonas Devlieghere
6d9ec4b24SWalter Erquinigoimport os
7d9ec4b24SWalter Erquinigo
8d9ec4b24SWalter Erquinigoimport lldbdap_testcase
901263c6cSJonas Devliegherefrom lldbsuite.test.decorators import *
1001263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import *
1101263c6cSJonas Devlieghere
1201263c6cSJonas Devlieghere
1301263c6cSJonas Devlieghereclass TestDAP_stackTrace(lldbdap_testcase.DAPTestCaseBase):
1401263c6cSJonas Devlieghere    name_key_path = ["name"]
1501263c6cSJonas Devlieghere    source_key_path = ["source", "path"]
1601263c6cSJonas Devlieghere    line_key_path = ["line"]
1701263c6cSJonas Devlieghere
18*5b4100ccSJohn Harrison    # stackTrace additioanl frames for paginated traces
19*5b4100ccSJohn Harrison    page_size = 20
20*5b4100ccSJohn Harrison
2101263c6cSJonas Devlieghere    def verify_stackFrames(self, start_idx, stackFrames):
2201263c6cSJonas Devlieghere        frame_idx = start_idx
2301263c6cSJonas Devlieghere        for stackFrame in stackFrames:
2401263c6cSJonas Devlieghere            # Don't care about frame above main
25*5b4100ccSJohn Harrison            if frame_idx > 40:
2601263c6cSJonas Devlieghere                return
2701263c6cSJonas Devlieghere            self.verify_stackFrame(frame_idx, stackFrame)
2801263c6cSJonas Devlieghere            frame_idx += 1
2901263c6cSJonas Devlieghere
3001263c6cSJonas Devlieghere    def verify_stackFrame(self, frame_idx, stackFrame):
3101263c6cSJonas Devlieghere        frame_name = self.get_dict_value(stackFrame, self.name_key_path)
3201263c6cSJonas Devlieghere        frame_source = self.get_dict_value(stackFrame, self.source_key_path)
3301263c6cSJonas Devlieghere        frame_line = self.get_dict_value(stackFrame, self.line_key_path)
3401263c6cSJonas Devlieghere        if frame_idx == 0:
3501263c6cSJonas Devlieghere            expected_line = self.recurse_end
3601263c6cSJonas Devlieghere            expected_name = "recurse"
37*5b4100ccSJohn Harrison        elif frame_idx < 40:
3801263c6cSJonas Devlieghere            expected_line = self.recurse_call
3901263c6cSJonas Devlieghere            expected_name = "recurse"
4001263c6cSJonas Devlieghere        else:
4101263c6cSJonas Devlieghere            expected_line = self.recurse_invocation
4201263c6cSJonas Devlieghere            expected_name = "main"
4380fcecb1SJonas Devlieghere        self.assertEqual(
4401263c6cSJonas Devlieghere            frame_name,
4501263c6cSJonas Devlieghere            expected_name,
4601263c6cSJonas Devlieghere            'frame #%i name "%s" == "%s"' % (frame_idx, frame_name, expected_name),
4701263c6cSJonas Devlieghere        )
4880fcecb1SJonas Devlieghere        self.assertEqual(
4901263c6cSJonas Devlieghere            frame_source,
5001263c6cSJonas Devlieghere            self.source_path,
5101263c6cSJonas Devlieghere            'frame #%i source "%s" == "%s"'
5201263c6cSJonas Devlieghere            % (frame_idx, frame_source, self.source_path),
5301263c6cSJonas Devlieghere        )
5480fcecb1SJonas Devlieghere        self.assertEqual(
5501263c6cSJonas Devlieghere            frame_line,
5601263c6cSJonas Devlieghere            expected_line,
5701263c6cSJonas Devlieghere            "frame #%i line %i == %i" % (frame_idx, frame_line, expected_line),
5801263c6cSJonas Devlieghere        )
5901263c6cSJonas Devlieghere
6001263c6cSJonas Devlieghere    @skipIfWindows
6101263c6cSJonas Devlieghere    def test_stackTrace(self):
6201263c6cSJonas Devlieghere        """
6301263c6cSJonas Devlieghere        Tests the 'stackTrace' packet and all its variants.
6401263c6cSJonas Devlieghere        """
6501263c6cSJonas Devlieghere        program = self.getBuildArtifact("a.out")
6601263c6cSJonas Devlieghere        self.build_and_launch(program)
6701263c6cSJonas Devlieghere        source = "main.c"
6801263c6cSJonas Devlieghere        self.source_path = os.path.join(os.getcwd(), source)
6901263c6cSJonas Devlieghere        self.recurse_end = line_number(source, "recurse end")
7001263c6cSJonas Devlieghere        self.recurse_call = line_number(source, "recurse call")
7101263c6cSJonas Devlieghere        self.recurse_invocation = line_number(source, "recurse invocation")
7201263c6cSJonas Devlieghere
7301263c6cSJonas Devlieghere        lines = [self.recurse_end]
7401263c6cSJonas Devlieghere
7501263c6cSJonas Devlieghere        # Set breakpoint at a point of deepest recuusion
7601263c6cSJonas Devlieghere        breakpoint_ids = self.set_source_breakpoints(source, lines)
7780fcecb1SJonas Devlieghere        self.assertEqual(
7801263c6cSJonas Devlieghere            len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
7901263c6cSJonas Devlieghere        )
8001263c6cSJonas Devlieghere
8101263c6cSJonas Devlieghere        self.continue_to_breakpoints(breakpoint_ids)
8201263c6cSJonas Devlieghere        startFrame = 0
8301263c6cSJonas Devlieghere        # Verify we get all stack frames with no arguments
8401263c6cSJonas Devlieghere        (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount()
8501263c6cSJonas Devlieghere        frameCount = len(stackFrames)
869c246882SJordan Rupprecht        self.assertGreaterEqual(
87*5b4100ccSJohn Harrison            frameCount, 40, "verify we get at least 40 frames for all frames"
8801263c6cSJonas Devlieghere        )
8980fcecb1SJonas Devlieghere        self.assertEqual(
90*5b4100ccSJohn Harrison            totalFrames,
91*5b4100ccSJohn Harrison            frameCount,
92*5b4100ccSJohn Harrison            "verify total frames returns a speculative page size",
93*5b4100ccSJohn Harrison        )
94*5b4100ccSJohn Harrison        self.verify_stackFrames(startFrame, stackFrames)
95*5b4100ccSJohn Harrison
96*5b4100ccSJohn Harrison        # Verify totalFrames contains a speculative page size of additional frames with startFrame = 0 and levels = 0
97*5b4100ccSJohn Harrison        (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount(
98*5b4100ccSJohn Harrison            startFrame=0, levels=10
99*5b4100ccSJohn Harrison        )
100*5b4100ccSJohn Harrison        self.assertEqual(len(stackFrames), 10, "verify we get levels=10 frames")
101*5b4100ccSJohn Harrison        self.assertEqual(
102*5b4100ccSJohn Harrison            totalFrames,
103*5b4100ccSJohn Harrison            len(stackFrames) + self.page_size,
104*5b4100ccSJohn Harrison            "verify total frames returns a speculative page size",
10501263c6cSJonas Devlieghere        )
10601263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
10701263c6cSJonas Devlieghere
10801263c6cSJonas Devlieghere        # Verify all stack frames by specifying startFrame = 0 and levels not
10901263c6cSJonas Devlieghere        # specified
11001263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame)
11180fcecb1SJonas Devlieghere        self.assertEqual(
11201263c6cSJonas Devlieghere            frameCount,
11301263c6cSJonas Devlieghere            len(stackFrames),
11401263c6cSJonas Devlieghere            ("verify same number of frames with startFrame=%i") % (startFrame),
11501263c6cSJonas Devlieghere        )
11601263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
11701263c6cSJonas Devlieghere
11801263c6cSJonas Devlieghere        # Verify all stack frames by specifying startFrame = 0 and levels = 0
11901263c6cSJonas Devlieghere        levels = 0
12001263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels)
12180fcecb1SJonas Devlieghere        self.assertEqual(
12201263c6cSJonas Devlieghere            frameCount,
12301263c6cSJonas Devlieghere            len(stackFrames),
12401263c6cSJonas Devlieghere            ("verify same number of frames with startFrame=%i and" " levels=%i")
12501263c6cSJonas Devlieghere            % (startFrame, levels),
12601263c6cSJonas Devlieghere        )
12701263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
12801263c6cSJonas Devlieghere
12901263c6cSJonas Devlieghere        # Get only the first stack frame by sepcifying startFrame = 0 and
13001263c6cSJonas Devlieghere        # levels = 1
13101263c6cSJonas Devlieghere        levels = 1
13201263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels)
13380fcecb1SJonas Devlieghere        self.assertEqual(
13401263c6cSJonas Devlieghere            levels,
13501263c6cSJonas Devlieghere            len(stackFrames),
13601263c6cSJonas Devlieghere            ("verify one frame with startFrame=%i and" " levels=%i")
13701263c6cSJonas Devlieghere            % (startFrame, levels),
13801263c6cSJonas Devlieghere        )
13901263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
14001263c6cSJonas Devlieghere
14101263c6cSJonas Devlieghere        # Get only the first 3 stack frames by sepcifying startFrame = 0 and
14201263c6cSJonas Devlieghere        # levels = 3
14301263c6cSJonas Devlieghere        levels = 3
14401263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels)
14580fcecb1SJonas Devlieghere        self.assertEqual(
14601263c6cSJonas Devlieghere            levels,
14701263c6cSJonas Devlieghere            len(stackFrames),
14801263c6cSJonas Devlieghere            ("verify %i frames with startFrame=%i and" " levels=%i")
14901263c6cSJonas Devlieghere            % (levels, startFrame, levels),
15001263c6cSJonas Devlieghere        )
15101263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
15201263c6cSJonas Devlieghere
15301263c6cSJonas Devlieghere        # Get only the first 15 stack frames by sepcifying startFrame = 5 and
15401263c6cSJonas Devlieghere        # levels = 16
15501263c6cSJonas Devlieghere        startFrame = 5
15601263c6cSJonas Devlieghere        levels = 16
15701263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels)
15880fcecb1SJonas Devlieghere        self.assertEqual(
15901263c6cSJonas Devlieghere            levels,
16001263c6cSJonas Devlieghere            len(stackFrames),
16101263c6cSJonas Devlieghere            ("verify %i frames with startFrame=%i and" " levels=%i")
16201263c6cSJonas Devlieghere            % (levels, startFrame, levels),
16301263c6cSJonas Devlieghere        )
16401263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
16501263c6cSJonas Devlieghere
16601263c6cSJonas Devlieghere        # Verify we cap things correctly when we ask for too many frames
16701263c6cSJonas Devlieghere        startFrame = 5
16801263c6cSJonas Devlieghere        levels = 1000
16901263c6cSJonas Devlieghere        (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount(
17001263c6cSJonas Devlieghere            startFrame=startFrame, levels=levels
17101263c6cSJonas Devlieghere        )
17280fcecb1SJonas Devlieghere        self.assertEqual(
17301263c6cSJonas Devlieghere            len(stackFrames),
17401263c6cSJonas Devlieghere            frameCount - startFrame,
17501263c6cSJonas Devlieghere            ("verify less than 1000 frames with startFrame=%i and" " levels=%i")
17601263c6cSJonas Devlieghere            % (startFrame, levels),
17701263c6cSJonas Devlieghere        )
17880fcecb1SJonas Devlieghere        self.assertEqual(
17901263c6cSJonas Devlieghere            totalFrames,
18001263c6cSJonas Devlieghere            frameCount,
18101263c6cSJonas Devlieghere            "verify we get correct value for totalFrames count "
18201263c6cSJonas Devlieghere            "when requested frames not from 0 index",
18301263c6cSJonas Devlieghere        )
18401263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
18501263c6cSJonas Devlieghere
18601263c6cSJonas Devlieghere        # Verify level=0 works with non-zerp start frame
18701263c6cSJonas Devlieghere        startFrame = 5
18801263c6cSJonas Devlieghere        levels = 0
18901263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels)
19080fcecb1SJonas Devlieghere        self.assertEqual(
19101263c6cSJonas Devlieghere            len(stackFrames),
19201263c6cSJonas Devlieghere            frameCount - startFrame,
19301263c6cSJonas Devlieghere            ("verify less than 1000 frames with startFrame=%i and" " levels=%i")
19401263c6cSJonas Devlieghere            % (startFrame, levels),
19501263c6cSJonas Devlieghere        )
19601263c6cSJonas Devlieghere        self.verify_stackFrames(startFrame, stackFrames)
19701263c6cSJonas Devlieghere
19801263c6cSJonas Devlieghere        # Verify we get not frames when startFrame is too high
19901263c6cSJonas Devlieghere        startFrame = 1000
20001263c6cSJonas Devlieghere        levels = 1
20101263c6cSJonas Devlieghere        stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels)
20280fcecb1SJonas Devlieghere        self.assertEqual(
20301263c6cSJonas Devlieghere            0, len(stackFrames), "verify zero frames with startFrame out of bounds"
20401263c6cSJonas Devlieghere        )
205d9ec4b24SWalter Erquinigo
206d9ec4b24SWalter Erquinigo    @skipIfWindows
207d9ec4b24SWalter Erquinigo    def test_functionNameWithArgs(self):
208d9ec4b24SWalter Erquinigo        """
209d9ec4b24SWalter Erquinigo        Test that the stack frame without a function name is given its pc in the response.
210d9ec4b24SWalter Erquinigo        """
211d9ec4b24SWalter Erquinigo        program = self.getBuildArtifact("a.out")
212d9ec4b24SWalter Erquinigo        self.build_and_launch(program, customFrameFormat="${function.name-with-args}")
213d9ec4b24SWalter Erquinigo        source = "main.c"
214d9ec4b24SWalter Erquinigo
215d9ec4b24SWalter Erquinigo        self.set_source_breakpoints(source, [line_number(source, "recurse end")])
216d9ec4b24SWalter Erquinigo
217d9ec4b24SWalter Erquinigo        self.continue_to_next_stop()
218d9ec4b24SWalter Erquinigo        frame = self.get_stackFrames()[0]
21980fcecb1SJonas Devlieghere        self.assertEqual(frame["name"], "recurse(x=1)")
220