1""" 2Test lldb-dap stackTrace request 3""" 4 5 6import os 7 8import lldbdap_testcase 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11 12 13class TestDAP_stackTrace(lldbdap_testcase.DAPTestCaseBase): 14 name_key_path = ["name"] 15 source_key_path = ["source", "path"] 16 line_key_path = ["line"] 17 18 # stackTrace additioanl frames for paginated traces 19 page_size = 20 20 21 def verify_stackFrames(self, start_idx, stackFrames): 22 frame_idx = start_idx 23 for stackFrame in stackFrames: 24 # Don't care about frame above main 25 if frame_idx > 40: 26 return 27 self.verify_stackFrame(frame_idx, stackFrame) 28 frame_idx += 1 29 30 def verify_stackFrame(self, frame_idx, stackFrame): 31 frame_name = self.get_dict_value(stackFrame, self.name_key_path) 32 frame_source = self.get_dict_value(stackFrame, self.source_key_path) 33 frame_line = self.get_dict_value(stackFrame, self.line_key_path) 34 if frame_idx == 0: 35 expected_line = self.recurse_end 36 expected_name = "recurse" 37 elif frame_idx < 40: 38 expected_line = self.recurse_call 39 expected_name = "recurse" 40 else: 41 expected_line = self.recurse_invocation 42 expected_name = "main" 43 self.assertEqual( 44 frame_name, 45 expected_name, 46 'frame #%i name "%s" == "%s"' % (frame_idx, frame_name, expected_name), 47 ) 48 self.assertEqual( 49 frame_source, 50 self.source_path, 51 'frame #%i source "%s" == "%s"' 52 % (frame_idx, frame_source, self.source_path), 53 ) 54 self.assertEqual( 55 frame_line, 56 expected_line, 57 "frame #%i line %i == %i" % (frame_idx, frame_line, expected_line), 58 ) 59 60 @skipIfWindows 61 def test_stackTrace(self): 62 """ 63 Tests the 'stackTrace' packet and all its variants. 64 """ 65 program = self.getBuildArtifact("a.out") 66 self.build_and_launch(program) 67 source = "main.c" 68 self.source_path = os.path.join(os.getcwd(), source) 69 self.recurse_end = line_number(source, "recurse end") 70 self.recurse_call = line_number(source, "recurse call") 71 self.recurse_invocation = line_number(source, "recurse invocation") 72 73 lines = [self.recurse_end] 74 75 # Set breakpoint at a point of deepest recuusion 76 breakpoint_ids = self.set_source_breakpoints(source, lines) 77 self.assertEqual( 78 len(breakpoint_ids), len(lines), "expect correct number of breakpoints" 79 ) 80 81 self.continue_to_breakpoints(breakpoint_ids) 82 startFrame = 0 83 # Verify we get all stack frames with no arguments 84 (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount() 85 frameCount = len(stackFrames) 86 self.assertGreaterEqual( 87 frameCount, 40, "verify we get at least 40 frames for all frames" 88 ) 89 self.assertEqual( 90 totalFrames, 91 frameCount, 92 "verify total frames returns a speculative page size", 93 ) 94 self.verify_stackFrames(startFrame, stackFrames) 95 96 # Verify totalFrames contains a speculative page size of additional frames with startFrame = 0 and levels = 0 97 (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount( 98 startFrame=0, levels=10 99 ) 100 self.assertEqual(len(stackFrames), 10, "verify we get levels=10 frames") 101 self.assertEqual( 102 totalFrames, 103 len(stackFrames) + self.page_size, 104 "verify total frames returns a speculative page size", 105 ) 106 self.verify_stackFrames(startFrame, stackFrames) 107 108 # Verify all stack frames by specifying startFrame = 0 and levels not 109 # specified 110 stackFrames = self.get_stackFrames(startFrame=startFrame) 111 self.assertEqual( 112 frameCount, 113 len(stackFrames), 114 ("verify same number of frames with startFrame=%i") % (startFrame), 115 ) 116 self.verify_stackFrames(startFrame, stackFrames) 117 118 # Verify all stack frames by specifying startFrame = 0 and levels = 0 119 levels = 0 120 stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels) 121 self.assertEqual( 122 frameCount, 123 len(stackFrames), 124 ("verify same number of frames with startFrame=%i and" " levels=%i") 125 % (startFrame, levels), 126 ) 127 self.verify_stackFrames(startFrame, stackFrames) 128 129 # Get only the first stack frame by sepcifying startFrame = 0 and 130 # levels = 1 131 levels = 1 132 stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels) 133 self.assertEqual( 134 levels, 135 len(stackFrames), 136 ("verify one frame with startFrame=%i and" " levels=%i") 137 % (startFrame, levels), 138 ) 139 self.verify_stackFrames(startFrame, stackFrames) 140 141 # Get only the first 3 stack frames by sepcifying startFrame = 0 and 142 # levels = 3 143 levels = 3 144 stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels) 145 self.assertEqual( 146 levels, 147 len(stackFrames), 148 ("verify %i frames with startFrame=%i and" " levels=%i") 149 % (levels, startFrame, levels), 150 ) 151 self.verify_stackFrames(startFrame, stackFrames) 152 153 # Get only the first 15 stack frames by sepcifying startFrame = 5 and 154 # levels = 16 155 startFrame = 5 156 levels = 16 157 stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels) 158 self.assertEqual( 159 levels, 160 len(stackFrames), 161 ("verify %i frames with startFrame=%i and" " levels=%i") 162 % (levels, startFrame, levels), 163 ) 164 self.verify_stackFrames(startFrame, stackFrames) 165 166 # Verify we cap things correctly when we ask for too many frames 167 startFrame = 5 168 levels = 1000 169 (stackFrames, totalFrames) = self.get_stackFrames_and_totalFramesCount( 170 startFrame=startFrame, levels=levels 171 ) 172 self.assertEqual( 173 len(stackFrames), 174 frameCount - startFrame, 175 ("verify less than 1000 frames with startFrame=%i and" " levels=%i") 176 % (startFrame, levels), 177 ) 178 self.assertEqual( 179 totalFrames, 180 frameCount, 181 "verify we get correct value for totalFrames count " 182 "when requested frames not from 0 index", 183 ) 184 self.verify_stackFrames(startFrame, stackFrames) 185 186 # Verify level=0 works with non-zerp start frame 187 startFrame = 5 188 levels = 0 189 stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels) 190 self.assertEqual( 191 len(stackFrames), 192 frameCount - startFrame, 193 ("verify less than 1000 frames with startFrame=%i and" " levels=%i") 194 % (startFrame, levels), 195 ) 196 self.verify_stackFrames(startFrame, stackFrames) 197 198 # Verify we get not frames when startFrame is too high 199 startFrame = 1000 200 levels = 1 201 stackFrames = self.get_stackFrames(startFrame=startFrame, levels=levels) 202 self.assertEqual( 203 0, len(stackFrames), "verify zero frames with startFrame out of bounds" 204 ) 205 206 @skipIfWindows 207 def test_functionNameWithArgs(self): 208 """ 209 Test that the stack frame without a function name is given its pc in the response. 210 """ 211 program = self.getBuildArtifact("a.out") 212 self.build_and_launch(program, customFrameFormat="${function.name-with-args}") 213 source = "main.c" 214 215 self.set_source_breakpoints(source, [line_number(source, "recurse end")]) 216 217 self.continue_to_next_stop() 218 frame = self.get_stackFrames()[0] 219 self.assertEqual(frame["name"], "recurse(x=1)") 220