1""" 2Test getting return-values correctly when stepping out 3""" 4 5import os, time 6import re 7import unittest2 8import lldb, lldbutil 9from lldbtest import * 10 11class ReturnValueTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "return-value") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @expectedFailurei386 17 @python_api_test 18 @dsym_test 19 def test_with_dsym_python(self): 20 """Test getting return values from stepping out with dsyms.""" 21 self.buildDsym() 22 self.do_return_value() 23 24 @expectedFailurei386 25 @python_api_test 26 @dwarf_test 27 def test_with_dwarf_python(self): 28 """Test getting return values from stepping out.""" 29 self.buildDwarf() 30 self.do_return_value() 31 32 def return_and_test_struct_value (self, func_name): 33 """Pass in the name of the function to return from - takes in value, returns value.""" 34 35 # Set the breakpoint, run to it, finish out. 36 bkpt = self.target.BreakpointCreateByName (func_name) 37 self.assertTrue (bkpt.GetNumResolvedLocations() > 0) 38 39 self.process.Continue () 40 41 thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, bkpt) 42 43 self.assertTrue (len(thread_list) == 1) 44 thread = thread_list[0] 45 46 self.target.BreakpointDelete (bkpt.GetID()) 47 48 in_value = thread.GetFrameAtIndex(0).FindVariable ("value") 49 50 self.assertTrue (in_value.IsValid()) 51 num_in_children = in_value.GetNumChildren() 52 53 # This is a little hokey, but if we don't get all the children now, then 54 # once we've stepped we won't be able to get them? 55 56 for idx in range(0, num_in_children): 57 in_child = in_value.GetChildAtIndex (idx) 58 in_child_str = in_child.GetValue() 59 60 thread.StepOut() 61 62 self.assertTrue (self.process.GetState() == lldb.eStateStopped) 63 self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) 64 65 # Assuming all these functions step out to main. Could figure out the caller dynamically 66 # if that would add something to the test. 67 frame = thread.GetFrameAtIndex(0) 68 fun_name = frame.GetFunctionName() 69 self.assertTrue (fun_name == "main") 70 71 frame = thread.GetFrameAtIndex(0) 72 ret_value = thread.GetStopReturnValue() 73 74 self.assertTrue (ret_value.IsValid()) 75 76 num_ret_children = ret_value.GetNumChildren() 77 self.assertTrue (num_in_children == num_ret_children) 78 for idx in range(0, num_ret_children): 79 in_child = in_value.GetChildAtIndex(idx) 80 ret_child = ret_value.GetChildAtIndex(idx) 81 in_child_str = in_child.GetValue() 82 ret_child_str = ret_child.GetValue() 83 84 self.assertTrue (in_child_str == ret_child_str) 85 86 def do_return_value(self): 87 """Test getting return values from stepping out.""" 88 exe = os.path.join(os.getcwd(), "a.out") 89 error = lldb.SBError() 90 91 self.target = self.dbg.CreateTarget(exe) 92 self.assertTrue(self.target, VALID_TARGET) 93 94 inner_sint_bkpt = self.target.BreakpointCreateByName("inner_sint", exe) 95 self.assertTrue(inner_sint_bkpt, VALID_BREAKPOINT) 96 97 # Now launch the process, and do not stop at entry point. 98 self.process = self.target.LaunchSimple(None, None, os.getcwd()) 99 100 self.assertTrue(self.process, PROCESS_IS_VALID) 101 102 # The stop reason of the thread should be breakpoint. 103 self.assertTrue(self.process.GetState() == lldb.eStateStopped, 104 STOPPED_DUE_TO_BREAKPOINT) 105 106 # Now finish, and make sure the return value is correct. 107 thread = lldbutil.get_stopped_thread (self.process, lldb.eStopReasonBreakpoint) 108 109 # inner_sint returns the variable value, so capture that here: 110 in_int = thread.GetFrameAtIndex(0).FindVariable ("value").GetValueAsSigned(error) 111 self.assertTrue (error.Success()) 112 113 thread.StepOut(); 114 115 self.assertTrue (self.process.GetState() == lldb.eStateStopped) 116 self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) 117 118 frame = thread.GetFrameAtIndex(0) 119 fun_name = frame.GetFunctionName() 120 self.assertTrue (fun_name == "outer_sint") 121 122 return_value = thread.GetStopReturnValue() 123 self.assertTrue (return_value.IsValid()) 124 125 ret_int = return_value.GetValueAsSigned(error) 126 self.assertTrue (error.Success()) 127 self.assertTrue (in_int == ret_int) 128 129 # Run again and we will stop in inner_sint the second time outer_sint is called. 130 #Then test stepping out two frames at once: 131 132 self.process.Continue() 133 thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_sint_bkpt) 134 self.assertTrue(len(thread_list) == 1) 135 thread = thread_list[0] 136 137 # We are done with the inner_sint breakpoint: 138 self.target.BreakpointDelete (inner_sint_bkpt.GetID()) 139 140 frame = thread.GetFrameAtIndex(1) 141 fun_name = frame.GetFunctionName () 142 self.assertTrue (fun_name == "outer_sint") 143 in_int = frame.FindVariable ("value").GetValueAsSigned(error) 144 self.assertTrue (error.Success()) 145 146 thread.StepOutOfFrame (frame) 147 148 self.assertTrue (self.process.GetState() == lldb.eStateStopped) 149 self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) 150 frame = thread.GetFrameAtIndex(0) 151 fun_name = frame.GetFunctionName() 152 self.assertTrue (fun_name == "main") 153 154 ret_value = thread.GetStopReturnValue() 155 self.assertTrue (return_value.IsValid()) 156 ret_int = ret_value.GetValueAsSigned (error) 157 self.assertTrue (error.Success()) 158 self.assertTrue (2 * in_int == ret_int) 159 160 # Now try some simple returns that have different types: 161 inner_float_bkpt = self.target.BreakpointCreateByName("inner_float", exe) 162 self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT) 163 self.process.Continue() 164 thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_float_bkpt) 165 self.assertTrue (len(thread_list) == 1) 166 thread = thread_list[0] 167 168 self.target.BreakpointDelete (inner_float_bkpt.GetID()) 169 170 frame = thread.GetFrameAtIndex(0) 171 in_value = frame.FindVariable ("value") 172 in_float = float (in_value.GetValue()) 173 thread.StepOut() 174 175 self.assertTrue (self.process.GetState() == lldb.eStateStopped) 176 self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) 177 178 frame = thread.GetFrameAtIndex(0) 179 fun_name = frame.GetFunctionName() 180 self.assertTrue (fun_name == "outer_float") 181 182 return_value = thread.GetStopReturnValue() 183 self.assertTrue (return_value.IsValid()) 184 return_float = float (return_value.GetValue()) 185 186 self.assertTrue(in_float == return_float) 187 188 self.return_and_test_struct_value ("return_one_int") 189 self.return_and_test_struct_value ("return_two_int") 190 self.return_and_test_struct_value ("return_three_int") 191 self.return_and_test_struct_value ("return_four_int") 192 self.return_and_test_struct_value ("return_five_int") 193 194 self.return_and_test_struct_value ("return_two_double") 195 self.return_and_test_struct_value ("return_one_double_two_float") 196 self.return_and_test_struct_value ("return_one_int_one_float_one_int") 197 198 self.return_and_test_struct_value ("return_one_pointer") 199 self.return_and_test_struct_value ("return_two_pointer") 200 self.return_and_test_struct_value ("return_one_float_one_pointer") 201 self.return_and_test_struct_value ("return_one_int_one_pointer") 202 self.return_and_test_struct_value ("return_three_short_one_float") 203 204 self.return_and_test_struct_value ("return_one_int_one_double") 205 self.return_and_test_struct_value ("return_one_int_one_double_one_int") 206 self.return_and_test_struct_value ("return_one_short_one_double_one_short") 207 self.return_and_test_struct_value ("return_one_float_one_int_one_float") 208 self.return_and_test_struct_value ("return_two_float") 209 # I am leaving out the packed test until we have a way to tell CLANG 210 # about alignment when reading DWARF for packed types. 211 #self.return_and_test_struct_value ("return_one_int_one_double_packed") 212 self.return_and_test_struct_value ("return_one_int_one_long") 213 214 # icc and gcc don't support this extension. 215 if self.getCompiler().endswith('clang'): 216 self.return_and_test_struct_value ("return_vector_size_float32") 217 self.return_and_test_struct_value ("return_ext_vector_size_float32") 218 219 220if __name__ == '__main__': 221 import atexit 222 lldb.SBDebugger.Initialize() 223 atexit.register(lambda: lldb.SBDebugger.Terminate()) 224 unittest2.main() 225