1""" 2Test thread step-in, step-over and step-out work with the "Avoid no debug" option. 3""" 4 5 6 7 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12 13 14class StepAvoidsNoDebugTestCase(TestBase): 15 16 @add_test_categories(['pyapi']) 17 @expectedFailureAll(archs=["aarch64"], oslist=["windows"], bugnumber="llvm.org/pr56292") 18 def test_step_out_with_python(self): 19 """Test stepping out using avoid-no-debug with dsyms.""" 20 self.build() 21 self.get_to_starting_point() 22 self.do_step_out_past_nodebug() 23 24 @add_test_categories(['pyapi']) 25 @decorators.expectedFailureAll( 26 compiler="gcc", bugnumber="llvm.org/pr28549") 27 @decorators.expectedFailureAll( 28 compiler="clang", 29 compiler_version=[ 30 ">=", 31 "3.9"], 32 archs=["i386"], 33 oslist=no_match(["freebsd"]), 34 bugnumber="llvm.org/pr28549") 35 @expectedFailureAll(archs=["aarch64"], oslist=["windows"], bugnumber="llvm.org/pr56292") 36 def test_step_over_with_python(self): 37 """Test stepping over using avoid-no-debug with dwarf.""" 38 self.build() 39 self.get_to_starting_point() 40 self.do_step_over_past_nodebug() 41 42 @add_test_categories(['pyapi']) 43 @decorators.expectedFailureAll( 44 compiler="gcc", bugnumber="llvm.org/pr28549") 45 @decorators.expectedFailureAll( 46 compiler="clang", 47 compiler_version=[ 48 ">=", 49 "3.9"], 50 archs=["i386"], 51 oslist=no_match(["freebsd"]), 52 bugnumber="llvm.org/pr28549") 53 @expectedFailureAll(archs=["aarch64"], oslist=["windows"], bugnumber="llvm.org/pr56292") 54 def test_step_in_with_python(self): 55 """Test stepping in using avoid-no-debug with dwarf.""" 56 self.build() 57 self.get_to_starting_point() 58 self.do_step_in_past_nodebug() 59 60 def setUp(self): 61 TestBase.setUp(self) 62 self.main_source = "with-debug.c" 63 self.main_source_spec = lldb.SBFileSpec("with-debug.c") 64 self.dbg.HandleCommand( 65 "settings set target.process.thread.step-out-avoid-nodebug true") 66 67 def tearDown(self): 68 self.dbg.HandleCommand( 69 "settings set target.process.thread.step-out-avoid-nodebug false") 70 TestBase.tearDown(self) 71 72 def hit_correct_line(self, pattern): 73 target_line = line_number(self.main_source, pattern) 74 self.assertTrue( 75 target_line != 0, 76 "Could not find source pattern " + 77 pattern) 78 cur_line = self.thread.frames[0].GetLineEntry().GetLine() 79 self.assertEqual( 80 cur_line, target_line, 81 "Stepped to line %d instead of expected %d with pattern '%s'." % 82 (cur_line, 83 target_line, 84 pattern)) 85 86 def hit_correct_function(self, pattern): 87 name = self.thread.frames[0].GetFunctionName() 88 self.assertTrue( 89 pattern in name, "Got to '%s' not the expected function '%s'." % 90 (name, pattern)) 91 92 def get_to_starting_point(self): 93 exe = self.getBuildArtifact("a.out") 94 error = lldb.SBError() 95 96 self.target = self.dbg.CreateTarget(exe) 97 self.assertTrue(self.target, VALID_TARGET) 98 99 inner_bkpt = self.target.BreakpointCreateBySourceRegex( 100 "Stop here and step out of me", self.main_source_spec) 101 self.assertTrue(inner_bkpt, VALID_BREAKPOINT) 102 103 # Now launch the process, and do not stop at entry point. 104 self.process = self.target.LaunchSimple( 105 None, None, self.get_process_working_directory()) 106 107 self.assertTrue(self.process, PROCESS_IS_VALID) 108 109 # Now finish, and make sure the return value is correct. 110 threads = lldbutil.get_threads_stopped_at_breakpoint( 111 self.process, inner_bkpt) 112 self.assertEquals(len(threads), 1, "Stopped at inner breakpoint.") 113 self.thread = threads[0] 114 115 def do_step_out_past_nodebug(self): 116 # The first step out takes us to the called_from_nodebug frame, just to make sure setting 117 # step-out-avoid-nodebug doesn't change the behavior in frames with 118 # debug info. 119 self.thread.StepOut() 120 self.hit_correct_line( 121 "intermediate_return_value = called_from_nodebug_actual(some_value)") 122 self.thread.StepOut() 123 self.hit_correct_line( 124 "int return_value = no_debug_caller(5, called_from_nodebug)") 125 126 def do_step_over_past_nodebug(self): 127 self.thread.StepOver() 128 self.hit_correct_line( 129 "intermediate_return_value = called_from_nodebug_actual(some_value)") 130 self.thread.StepOver() 131 self.hit_correct_line("return intermediate_return_value") 132 self.thread.StepOver() 133 # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in" 134 # when exiting a frame. In all cases we leave the pc at the point where we exited the 135 # frame. In gdb, step-over/step-in move to the end of the line they stepped out to. 136 # If we ever change this we will need to fix this test. 137 self.hit_correct_line( 138 "int return_value = no_debug_caller(5, called_from_nodebug)") 139 140 def do_step_in_past_nodebug(self): 141 self.thread.StepInto() 142 self.hit_correct_line( 143 "intermediate_return_value = called_from_nodebug_actual(some_value)") 144 self.thread.StepInto() 145 self.hit_correct_line("return intermediate_return_value") 146 self.thread.StepInto() 147 # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in" 148 # when exiting a frame. In all cases we leave the pc at the point where we exited the 149 # frame. In gdb, step-over/step-in move to the end of the line they stepped out to. 150 # If we ever change this we will need to fix this test. 151 self.hit_correct_line( 152 "int return_value = no_debug_caller(5, called_from_nodebug)") 153