10a840ef8STatyana Krasnukha""" 20a840ef8STatyana KrasnukhaTest that line information is recalculated properly for a frame when it moves 30a840ef8STatyana Krasnukhafrom the middle of the backtrace to a zero index. 40a840ef8STatyana Krasnukha 50a840ef8STatyana KrasnukhaThis is a regression test for a StackFrame bug, where whether frame is zero or 60a840ef8STatyana Krasnukhanot depends on an internal field. When LLDB was updating its frame list value 70a840ef8STatyana Krasnukhaof the field wasn't copied into existing StackFrame instances, so those 80a840ef8STatyana KrasnukhaStackFrame instances, would use an incorrect line entry evaluation logic in 90a840ef8STatyana Krasnukhasituations if it was in the middle of the stack frame list (not zeroth), and 100a840ef8STatyana Krasnukhathen moved to the top position. The difference in logic is that for zeroth 110a840ef8STatyana Krasnukhaframes line entry is returned for program counter, while for other frame 120a840ef8STatyana Krasnukha(except for those that "behave like zeroth") it is for the instruction 130a840ef8STatyana Krasnukhapreceding PC, as PC points to the next instruction after function call. When 140a840ef8STatyana Krasnukhathe bug is present, when execution stops at the second breakpoint 150a840ef8STatyana KrasnukhaSBFrame.GetLineEntry() returns line entry for the previous line, rather than 160a840ef8STatyana Krasnukhathe one with a breakpoint. Note that this is specific to 170a840ef8STatyana KrasnukhaSBFrame.GetLineEntry(), SBFrame.GetPCAddress().GetLineEntry() would return 180a840ef8STatyana Krasnukhacorrect entry. 190a840ef8STatyana Krasnukha 200a840ef8STatyana KrasnukhaThis bug doesn't reproduce through an LLDB interpretator, however it happens 210a840ef8STatyana Krasnukhawhen using API directly, for example in LLDB-MI. 220a840ef8STatyana Krasnukha""" 230a840ef8STatyana Krasnukha 240a840ef8STatyana Krasnukhaimport lldb 250a840ef8STatyana Krasnukhafrom lldbsuite.test.decorators import * 260a840ef8STatyana Krasnukhafrom lldbsuite.test.lldbtest import * 270a840ef8STatyana Krasnukhafrom lldbsuite.test import lldbutil 280a840ef8STatyana Krasnukha 290a840ef8STatyana Krasnukha 300a840ef8STatyana Krasnukhaclass ZerothFrame(TestBase): 310a840ef8STatyana Krasnukha def test(self): 320a840ef8STatyana Krasnukha """ 330a840ef8STatyana Krasnukha Test that line information is recalculated properly for a frame when it moves 340a840ef8STatyana Krasnukha from the middle of the backtrace to a zero index. 350a840ef8STatyana Krasnukha """ 360a840ef8STatyana Krasnukha self.build() 370a840ef8STatyana Krasnukha self.setTearDownCleanup() 380a840ef8STatyana Krasnukha 390a840ef8STatyana Krasnukha exe = self.getBuildArtifact("a.out") 400a840ef8STatyana Krasnukha target = self.dbg.CreateTarget(exe) 410a840ef8STatyana Krasnukha self.assertTrue(target, VALID_TARGET) 420a840ef8STatyana Krasnukha 43*4c236253SKendal Harland main_dot_c = lldb.SBFileSpec("main.c") 44*4c236253SKendal Harland bp1 = target.BreakpointCreateBySourceRegex( 45*4c236253SKendal Harland "// Set breakpoint 1 here", main_dot_c 462238dcc3SJonas Devlieghere ) 47*4c236253SKendal Harland bp2 = target.BreakpointCreateBySourceRegex( 48*4c236253SKendal Harland "// Set breakpoint 2 here", main_dot_c 492238dcc3SJonas Devlieghere ) 500a840ef8STatyana Krasnukha 512238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 520a840ef8STatyana Krasnukha self.assertTrue(process, VALID_PROCESS) 530a840ef8STatyana Krasnukha 54*4c236253SKendal Harland thread = self.thread() 55*4c236253SKendal Harland 560a840ef8STatyana Krasnukha if self.TraceOn(): 570a840ef8STatyana Krasnukha print("Backtrace at the first breakpoint:") 580a840ef8STatyana Krasnukha for f in thread.frames: 590a840ef8STatyana Krasnukha print(f) 60*4c236253SKendal Harland 610a840ef8STatyana Krasnukha # Check that we have stopped at correct breakpoint. 620a840ef8STatyana Krasnukha self.assertEqual( 63*4c236253SKendal Harland thread.frame[0].GetLineEntry().GetLine(), 64*4c236253SKendal Harland bp1.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(), 652238dcc3SJonas Devlieghere "LLDB reported incorrect line number.", 662238dcc3SJonas Devlieghere ) 670a840ef8STatyana Krasnukha 680a840ef8STatyana Krasnukha # Important to use SBProcess::Continue() instead of 690a840ef8STatyana Krasnukha # self.runCmd('continue'), because the problem doesn't reproduce with 700a840ef8STatyana Krasnukha # 'continue' command. 710a840ef8STatyana Krasnukha process.Continue() 720a840ef8STatyana Krasnukha 730a840ef8STatyana Krasnukha if self.TraceOn(): 740a840ef8STatyana Krasnukha print("Backtrace at the second breakpoint:") 750a840ef8STatyana Krasnukha for f in thread.frames: 760a840ef8STatyana Krasnukha print(f) 770a840ef8STatyana Krasnukha # Check that we have stopped at the breakpoint 780a840ef8STatyana Krasnukha self.assertEqual( 790a840ef8STatyana Krasnukha thread.frame[0].GetLineEntry().GetLine(), 80*4c236253SKendal Harland bp2.GetLocationAtIndex(0).GetAddress().GetLineEntry().GetLine(), 812238dcc3SJonas Devlieghere "LLDB reported incorrect line number.", 822238dcc3SJonas Devlieghere ) 830a840ef8STatyana Krasnukha # Double-check with GetPCAddress() 840a840ef8STatyana Krasnukha self.assertEqual( 850a840ef8STatyana Krasnukha thread.frame[0].GetLineEntry().GetLine(), 860a840ef8STatyana Krasnukha thread.frame[0].GetPCAddress().GetLineEntry().GetLine(), 872238dcc3SJonas Devlieghere "LLDB reported incorrect line number.", 882238dcc3SJonas Devlieghere ) 89