diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities/return-value')
3 files changed, 626 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/Makefile b/packages/Python/lldbsuite/test/functionalities/return-value/Makefile new file mode 100644 index 000000000000..cb03eabfc274 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/return-value/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := call-func.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py new file mode 100644 index 000000000000..246eb5c3fdbd --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py @@ -0,0 +1,214 @@ +""" +Test getting return-values correctly when stepping out +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class ReturnValueTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=["macosx","freebsd"], archs=["i386"]) + @expectedFailureAll(oslist=["linux"], compiler="clang", compiler_version=["<=", "3.6"], archs=["i386"]) + @expectedFailureAll(bugnumber="llvm.org/pr25785", hostoslist=["windows"], compiler="gcc", archs=["i386"], triple='.*-android') + @expectedFailureWindows("llvm.org/pr24778") + @add_test_categories(['pyapi']) + def test_with_python(self): + """Test getting return values from stepping out.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + error = lldb.SBError() + + self.target = self.dbg.CreateTarget(exe) + self.assertTrue(self.target, VALID_TARGET) + + inner_sint_bkpt = self.target.BreakpointCreateByName("inner_sint", exe) + self.assertTrue(inner_sint_bkpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + self.process = self.target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(self.process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.assertTrue(self.process.GetState() == lldb.eStateStopped, + STOPPED_DUE_TO_BREAKPOINT) + + # Now finish, and make sure the return value is correct. + thread = lldbutil.get_stopped_thread (self.process, lldb.eStopReasonBreakpoint) + + # inner_sint returns the variable value, so capture that here: + in_int = thread.GetFrameAtIndex(0).FindVariable ("value").GetValueAsSigned(error) + self.assertTrue (error.Success()) + + thread.StepOut(); + + self.assertTrue (self.process.GetState() == lldb.eStateStopped) + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + frame = thread.GetFrameAtIndex(0) + fun_name = frame.GetFunctionName() + self.assertTrue (fun_name == "outer_sint") + + return_value = thread.GetStopReturnValue() + self.assertTrue (return_value.IsValid()) + + ret_int = return_value.GetValueAsSigned(error) + self.assertTrue (error.Success()) + self.assertTrue (in_int == ret_int) + + # Run again and we will stop in inner_sint the second time outer_sint is called. + #Then test stepping out two frames at once: + + self.process.Continue() + thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_sint_bkpt) + self.assertTrue(len(thread_list) == 1) + thread = thread_list[0] + + # We are done with the inner_sint breakpoint: + self.target.BreakpointDelete (inner_sint_bkpt.GetID()) + + frame = thread.GetFrameAtIndex(1) + fun_name = frame.GetFunctionName () + self.assertTrue (fun_name == "outer_sint") + in_int = frame.FindVariable ("value").GetValueAsSigned(error) + self.assertTrue (error.Success()) + + thread.StepOutOfFrame (frame) + + self.assertTrue (self.process.GetState() == lldb.eStateStopped) + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + frame = thread.GetFrameAtIndex(0) + fun_name = frame.GetFunctionName() + self.assertTrue (fun_name == "main") + + ret_value = thread.GetStopReturnValue() + self.assertTrue (return_value.IsValid()) + ret_int = ret_value.GetValueAsSigned (error) + self.assertTrue (error.Success()) + self.assertTrue (2 * in_int == ret_int) + + # Now try some simple returns that have different types: + inner_float_bkpt = self.target.BreakpointCreateByName("inner_float", exe) + self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT) + self.process.Continue() + thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, inner_float_bkpt) + self.assertTrue (len(thread_list) == 1) + thread = thread_list[0] + + self.target.BreakpointDelete (inner_float_bkpt.GetID()) + + frame = thread.GetFrameAtIndex(0) + in_value = frame.FindVariable ("value") + in_float = float (in_value.GetValue()) + thread.StepOut() + + self.assertTrue (self.process.GetState() == lldb.eStateStopped) + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + frame = thread.GetFrameAtIndex(0) + fun_name = frame.GetFunctionName() + self.assertTrue (fun_name == "outer_float") + + return_value = thread.GetStopReturnValue() + self.assertTrue (return_value.IsValid()) + return_float = float (return_value.GetValue()) + + self.assertTrue(in_float == return_float) + + self.return_and_test_struct_value ("return_one_int") + self.return_and_test_struct_value ("return_two_int") + self.return_and_test_struct_value ("return_three_int") + self.return_and_test_struct_value ("return_four_int") + self.return_and_test_struct_value ("return_five_int") + + self.return_and_test_struct_value ("return_two_double") + self.return_and_test_struct_value ("return_one_double_two_float") + self.return_and_test_struct_value ("return_one_int_one_float_one_int") + + self.return_and_test_struct_value ("return_one_pointer") + self.return_and_test_struct_value ("return_two_pointer") + self.return_and_test_struct_value ("return_one_float_one_pointer") + self.return_and_test_struct_value ("return_one_int_one_pointer") + self.return_and_test_struct_value ("return_three_short_one_float") + + self.return_and_test_struct_value ("return_one_int_one_double") + self.return_and_test_struct_value ("return_one_int_one_double_one_int") + self.return_and_test_struct_value ("return_one_short_one_double_one_short") + self.return_and_test_struct_value ("return_one_float_one_int_one_float") + self.return_and_test_struct_value ("return_two_float") + # I am leaving out the packed test until we have a way to tell CLANG + # about alignment when reading DWARF for packed types. + #self.return_and_test_struct_value ("return_one_int_one_double_packed") + self.return_and_test_struct_value ("return_one_int_one_long") + + # icc and gcc don't support this extension. + if self.getCompiler().endswith('clang'): + self.return_and_test_struct_value ("return_vector_size_float32_8") + self.return_and_test_struct_value ("return_vector_size_float32_16") + self.return_and_test_struct_value ("return_vector_size_float32_32") + self.return_and_test_struct_value ("return_ext_vector_size_float32_2") + self.return_and_test_struct_value ("return_ext_vector_size_float32_4") + self.return_and_test_struct_value ("return_ext_vector_size_float32_8") + + def return_and_test_struct_value (self, func_name): + """Pass in the name of the function to return from - takes in value, returns value.""" + + # Set the breakpoint, run to it, finish out. + bkpt = self.target.BreakpointCreateByName (func_name) + self.assertTrue (bkpt.GetNumResolvedLocations() > 0) + + self.process.Continue () + + thread_list = lldbutil.get_threads_stopped_at_breakpoint (self.process, bkpt) + + self.assertTrue (len(thread_list) == 1) + thread = thread_list[0] + + self.target.BreakpointDelete (bkpt.GetID()) + + in_value = thread.GetFrameAtIndex(0).FindVariable ("value") + + self.assertTrue (in_value.IsValid()) + num_in_children = in_value.GetNumChildren() + + # This is a little hokey, but if we don't get all the children now, then + # once we've stepped we won't be able to get them? + + for idx in range(0, num_in_children): + in_child = in_value.GetChildAtIndex (idx) + in_child_str = in_child.GetValue() + + thread.StepOut() + + self.assertTrue (self.process.GetState() == lldb.eStateStopped) + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # Assuming all these functions step out to main. Could figure out the caller dynamically + # if that would add something to the test. + frame = thread.GetFrameAtIndex(0) + fun_name = frame.GetFunctionName() + self.assertTrue (fun_name == "main") + + frame = thread.GetFrameAtIndex(0) + ret_value = thread.GetStopReturnValue() + + self.assertTrue (ret_value.IsValid()) + + num_ret_children = ret_value.GetNumChildren() + self.assertTrue (num_in_children == num_ret_children) + for idx in range(0, num_ret_children): + in_child = in_value.GetChildAtIndex(idx) + ret_child = ret_value.GetChildAtIndex(idx) + in_child_str = in_child.GetValue() + ret_child_str = ret_child.GetValue() + + self.assertEqual(in_child_str, ret_child_str) diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/call-func.c b/packages/Python/lldbsuite/test/functionalities/return-value/call-func.c new file mode 100644 index 000000000000..0c026ffcca17 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/return-value/call-func.c @@ -0,0 +1,407 @@ +// Some convenient things to return: +static char *g_first_pointer = "I am the first"; +static char *g_second_pointer = "I am the second"; + +// First we have some simple functions that return standard types, ints, floats and doubles. +// We have a function calling a function in a few cases to test that if you stop in the +// inner function then do "up/fin" you get the return value from the outer-most frame. + +int +inner_sint (int value) +{ + return value; +} + +int +outer_sint (int value) +{ + int outer_value = 2 * inner_sint (value); + return outer_value; +} + +float +inner_float (float value) +{ + return value; +} + +float +outer_float (float value) +{ + float outer_value = 2 * inner_float(value); + return outer_value; +} + +double +return_double (double value) +{ + return value; +} + +long double +return_long_double (long double value) +{ + return value; +} + +char * +return_pointer (char *value) +{ + return value; +} + +struct one_int +{ + int one_field; +}; + +struct one_int +return_one_int (struct one_int value) +{ + return value; +} + +struct two_int +{ + int first_field; + int second_field; +}; + +struct two_int +return_two_int (struct two_int value) +{ + return value; +} + +struct three_int +{ + int first_field; + int second_field; + int third_field; +}; + +struct three_int +return_three_int (struct three_int value) +{ + return value; +} + +struct four_int +{ + int first_field; + int second_field; + int third_field; + int fourth_field; +}; + +struct four_int +return_four_int (struct four_int value) +{ + return value; +} + +struct five_int +{ + int first_field; + int second_field; + int third_field; + int fourth_field; + int fifth_field; +}; + +struct five_int +return_five_int (struct five_int value) +{ + return value; +} + +struct one_int_one_double +{ + int first_field; + double second_field; +}; + +struct one_int_one_double +return_one_int_one_double (struct one_int_one_double value) +{ + return value; +} + +struct one_int_one_double_one_int +{ + int one_field; + double second_field; + int third_field; +}; + +struct one_int_one_double_one_int +return_one_int_one_double_one_int (struct one_int_one_double_one_int value) +{ + return value; +} + +struct one_short_one_double_one_short +{ + int one_field; + double second_field; + int third_field; +}; + +struct one_short_one_double_one_short +return_one_short_one_double_one_short (struct one_short_one_double_one_short value) +{ + return value; +} + +struct three_short_one_float +{ + short one_field; + short second_field; + short third_field; + float fourth_field; +}; + +struct three_short_one_float +return_three_short_one_float (struct three_short_one_float value) +{ + return value; +} + +struct one_int_one_float_one_int +{ + int one_field; + float second_field; + int third_field; +}; + +struct one_int_one_float_one_int +return_one_int_one_float_one_int (struct one_int_one_float_one_int value) +{ + return value; +} + +struct one_float_one_int_one_float +{ + float one_field; + int second_field; + float third_field; +}; + +struct one_float_one_int_one_float +return_one_float_one_int_one_float (struct one_float_one_int_one_float value) +{ + return value; +} + +struct one_double_two_float +{ + double one_field; + float second_field; + float third_field; +}; + +struct one_double_two_float +return_one_double_two_float (struct one_double_two_float value) +{ + return value; +} + +struct two_double +{ + double first_field; + double second_field; +}; + +struct two_double +return_two_double (struct two_double value) +{ + return value; +} + +struct two_float +{ + float first_field; + float second_field; +}; + +struct two_float +return_two_float (struct two_float value) +{ + return value; +} + +struct one_int_one_double_packed +{ + int first_field; + double second_field; +} __attribute__((__packed__)); + +struct one_int_one_double_packed +return_one_int_one_double_packed (struct one_int_one_double_packed value) +{ + return value; +} + +struct one_int_one_long +{ + int first_field; + long second_field; +}; + +struct one_int_one_long +return_one_int_one_long (struct one_int_one_long value) +{ + return value; +} + +struct one_pointer +{ + char *first_field; +}; + +struct one_pointer +return_one_pointer (struct one_pointer value) +{ + return value; +} + +struct two_pointer +{ + char *first_field; + char *second_field; +}; + +struct two_pointer +return_two_pointer (struct two_pointer value) +{ + return value; +} + +struct one_float_one_pointer +{ + float first_field; + char *second_field; +}; + +struct one_float_one_pointer +return_one_float_one_pointer (struct one_float_one_pointer value) +{ + return value; +} + +struct one_int_one_pointer +{ + int first_field; + char *second_field; +}; + +struct one_int_one_pointer +return_one_int_one_pointer (struct one_int_one_pointer value) +{ + return value; +} + +typedef float vector_size_float32_8 __attribute__((__vector_size__(8))); +typedef float vector_size_float32_16 __attribute__((__vector_size__(16))); +typedef float vector_size_float32_32 __attribute__((__vector_size__(32))); + +typedef float ext_vector_size_float32_2 __attribute__((ext_vector_type(2))); +typedef float ext_vector_size_float32_4 __attribute__((ext_vector_type(4))); +typedef float ext_vector_size_float32_8 __attribute__((ext_vector_type(8))); + +vector_size_float32_8 +return_vector_size_float32_8 (vector_size_float32_8 value) +{ + return value; +} + +vector_size_float32_16 +return_vector_size_float32_16 (vector_size_float32_16 value) +{ + return value; +} + +vector_size_float32_32 +return_vector_size_float32_32 (vector_size_float32_32 value) +{ + return value; +} + +ext_vector_size_float32_2 +return_ext_vector_size_float32_2 (ext_vector_size_float32_2 value) +{ + return value; +} + +ext_vector_size_float32_4 +return_ext_vector_size_float32_4 (ext_vector_size_float32_4 value) +{ + return value; +} + +ext_vector_size_float32_8 +return_ext_vector_size_float32_8 (ext_vector_size_float32_8 value) +{ + return value; +} + +int +main () +{ + int first_int = 123456; + int second_int = 234567; + + outer_sint (first_int); + outer_sint (second_int); + + float first_float_value = 12.34; + float second_float_value = 23.45; + + outer_float (first_float_value); + outer_float (second_float_value); + + double double_value = -23.45; + + return_double (double_value); + + return_pointer(g_first_pointer); + + long double long_double_value = -3456789.987654321; + + return_long_double (long_double_value); + + // Okay, now the structures: + return_one_int ((struct one_int) {10}); + return_two_int ((struct two_int) {10, 20}); + return_three_int ((struct three_int) {10, 20, 30}); + return_four_int ((struct four_int) {10, 20, 30, 40}); + return_five_int ((struct five_int) {10, 20, 30, 40, 50}); + + return_two_double ((struct two_double) {10.0, 20.0}); + return_one_double_two_float ((struct one_double_two_float) {10.0, 20.0, 30.0}); + return_one_int_one_float_one_int ((struct one_int_one_float_one_int) {10, 20.0, 30}); + + return_one_pointer ((struct one_pointer) {g_first_pointer}); + return_two_pointer ((struct two_pointer) {g_first_pointer, g_second_pointer}); + return_one_float_one_pointer ((struct one_float_one_pointer) {10.0, g_first_pointer}); + return_one_int_one_pointer ((struct one_int_one_pointer) {10, g_first_pointer}); + return_three_short_one_float ((struct three_short_one_float) {10, 20, 30, 40.0}); + + return_one_int_one_double ((struct one_int_one_double) {10, 20.0}); + return_one_int_one_double_one_int ((struct one_int_one_double_one_int) {10, 20.0, 30}); + return_one_short_one_double_one_short ((struct one_short_one_double_one_short) {10, 20.0, 30}); + return_one_float_one_int_one_float ((struct one_float_one_int_one_float) {10.0, 20, 30.0}); + return_two_float ((struct two_float) { 10.0, 20.0}); + return_one_int_one_double_packed ((struct one_int_one_double_packed) {10, 20.0}); + return_one_int_one_long ((struct one_int_one_long) {10, 20}); + + return_vector_size_float32_8 (( vector_size_float32_8 ){1.5, 2.25}); + return_vector_size_float32_16 (( vector_size_float32_16 ){1.5, 2.25, 4.125, 8.0625}); + return_vector_size_float32_32 (( vector_size_float32_32 ){1.5, 2.25, 4.125, 8.0625, 7.89, 8.52, 6.31, 9.12}); + + return_ext_vector_size_float32_2 ((ext_vector_size_float32_2){ 16.5, 32.25}); + return_ext_vector_size_float32_4 ((ext_vector_size_float32_4){ 16.5, 32.25, 64.125, 128.0625}); + return_ext_vector_size_float32_8 ((ext_vector_size_float32_8){ 16.5, 32.25, 64.125, 128.0625, 1.59, 3.57, 8.63, 9.12 }); + + return 0; +} |