diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/lang/c')
75 files changed, 2876 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/lang/c/anonymous/Makefile b/packages/Python/lldbsuite/test/lang/c/anonymous/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/anonymous/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py b/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py new file mode 100644 index 0000000..7cb66ba --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py @@ -0,0 +1,147 @@ +"""Test that anonymous structs/unions are transparent to member access""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class AnonymousTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfIcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC + def test_expr_nest(self): + self.build() + self.common_setup(self.line0) + + # These should display correctly. + self.expect("expression n->foo.d", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 4"]) + + self.expect("expression n->b", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 2"]) + + def test_expr_child(self): + self.build() + self.common_setup(self.line1) + + # These should display correctly. + self.expect("expression c->foo.d", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 4"]) + + self.expect("expression c->grandchild.b", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 2"]) + + @skipIfIcc # llvm.org/pr15036: This particular regression was introduced by r181498 + def test_expr_grandchild(self): + self.build() + self.common_setup(self.line2) + + # These should display correctly. + self.expect("expression g.child.foo.d", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 4"]) + + self.expect("expression g.child.b", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 2"]) + + def test_expr_parent(self): + self.build() + if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): + self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") + self.common_setup(self.line2) + + # These should display correctly. + self.expect("expression pz", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(type_z *) $", " = 0x0000"]) + + self.expect("expression z.y", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(type_y) $", "dummy = 2"]) + + @expectedFailureWindows('llvm.org/pr21550') + def test_expr_null(self): + self.build() + self.common_setup(self.line2) + + # This should fail because pz is 0, but it succeeds on OS/X. + # This fails on Linux with an upstream error "Couldn't dematerialize struct", as does "p *n" with "int *n = 0". + # Note that this can also trigger llvm.org/pr15036 when run interactively at the lldb command prompt. + self.expect("expression *(type_z *)pz", error = True) + + def test_child_by_name(self): + self.build() + + # Set debugger into synchronous mode + self.dbg.SetAsync(False) + + # Create a target + exe = os.path.join (os.getcwd(), "a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + break_in_main = target.BreakpointCreateBySourceRegex ('// Set breakpoint 2 here.', lldb.SBFileSpec(self.source)) + self.assertTrue(break_in_main, VALID_BREAKPOINT) + + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + self.assertTrue (process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in main.") + + thread = threads[0] + frame = thread.frames[0] + + if not frame.IsValid(): + self.fail ("Failed to get frame 0.") + + var_n = frame.FindVariable("n") + if not var_n.IsValid(): + self.fail ("Failed to get the variable 'n'") + + elem_a = var_n.GetChildMemberWithName("a") + if not elem_a.IsValid(): + self.fail ("Failed to get the element a in n") + + error = lldb.SBError() + value = elem_a.GetValueAsSigned(error, 1000) + if not error.Success() or value != 0: + self.fail ("failed to get the correct value for element a in n") + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break in main.c. + self.source = 'main.c' + self.line0 = line_number(self.source, '// Set breakpoint 0 here.') + self.line1 = line_number(self.source, '// Set breakpoint 1 here.') + self.line2 = line_number(self.source, '// Set breakpoint 2 here.') + + def common_setup(self, line): + + # Set debugger into synchronous mode + self.dbg.SetAsync(False) + + # Create a target + exe = os.path.join(os.getcwd(), "a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set breakpoints inside and outside methods that take pointers to the containing struct. + lldbutil.run_break_set_by_file_and_line (self, self.source, line, num_expected_locations=1, loc_exact=True) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) diff --git a/packages/Python/lldbsuite/test/lang/c/anonymous/main.c b/packages/Python/lldbsuite/test/lang/c/anonymous/main.c new file mode 100644 index 0000000..58ac85b --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/anonymous/main.c @@ -0,0 +1,82 @@ +#include <stdio.h> + +struct anonymous_nest { + struct { + struct { + int a; + int b; + }; // anonymous + struct { + int c; + int d; + } foo; + }; // anonymous +}; + +struct anonymous_child { + struct { + struct { + int a; + int b; + } grandchild; + struct { + int c; + int d; + } foo; + }; // anonymous +}; + +struct anonymous_grandchild { + struct { + struct { + int a; + int b; + }; // anonymous + struct { + int c; + int d; + } foo; + } child; +}; + +int processor_nest (struct anonymous_nest *n) +{ + return n->foo.d + n->b; // Set breakpoint 0 here. +} + +int processor_child (struct anonymous_child *c) +{ + return c->foo.d + c->grandchild.b; // Set breakpoint 1 here. +} + +int processor_grandchild (struct anonymous_grandchild *g) +{ + return g->child.foo.d + g->child.b; +} + + + +typedef struct { + int dummy; +} type_y; + +typedef struct { + type_y y; +} type_z; + + + +int main() +{ + struct anonymous_nest n = { 0, 2, 0, 4 }; + struct anonymous_child c = { 0, 2, 0, 4 }; + struct anonymous_grandchild g = { 0, 2, 0, 4 }; + type_z *pz = 0; + type_z z = {{2}}; + + printf("%d\n", processor_nest(&n)); + printf("%d\n", processor_child(&c)); + printf("%d\n", processor_grandchild(&g)); // Set breakpoint 2 here. + + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/array_types/Makefile b/packages/Python/lldbsuite/test/lang/c/array_types/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/array_types/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py b/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py new file mode 100644 index 0000000..e835fb0 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py @@ -0,0 +1,198 @@ +"""Test breakpoint by file/line number; and list variables with array types.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class ArrayTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test_and_run_command(self): + """Test 'frame variable var_name' on some variables with array types.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False) + + self.runCmd("run", RUN_SUCCEEDED) + + # The test suite sometimes shows that the process has exited without stopping. + # + # CC=clang ./dotest.py -v -t array_types + # ... + # Process 76604 exited with status = 0 (0x00000000) + self.runCmd("process status") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = ['resolved, hit count = 1']) + + # Issue 'variable list' command on several array-type variables. + + self.expect("frame variable --show-types strings", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(char *[4])', + substrs = ['(char *) [0]', + '(char *) [1]', + '(char *) [2]', + '(char *) [3]', + 'Hello', + 'Hola', + 'Bonjour', + 'Guten Tag']) + + self.expect("frame variable --show-types --raw -- char_16", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(char) [0]', + '(char) [15]']) + + self.expect("frame variable --show-types ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(unsigned short [2][3])') + + self.expect("frame variable --show-types long_6", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(long [6])') + + @add_test_categories(['pyapi']) + def test_and_python_api(self): + """Use Python APIs to inspect variables with array types.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Sanity check the print representation of breakpoint. + bp = str(breakpoint) + self.expect(bp, msg="Breakpoint looks good", exe=False, + substrs = ["file = 'main.c'", + "line = %d" % self.line, + "locations = 1"]) + self.expect(bp, msg="Breakpoint is not resolved as yet", exe=False, matching=False, + substrs = ["resolved = 1"]) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # Sanity check the print representation of process. + proc = str(process) + self.expect(proc, msg="Process looks good", exe=False, + substrs = ["state = stopped", + "executable = a.out"]) + + # The stop reason of the thread should be breakpoint. + thread = process.GetThreadAtIndex(0) + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + from lldbsuite.test.lldbutil import stop_reason_to_str + self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % + stop_reason_to_str(thread.GetStopReason())) + + # Sanity check the print representation of thread. + thr = str(thread) + # TODO(zturner): Whether the TID is printed in hex or decimal should be controlled by a setting, + # and this test should read the value of the setting. This check is currently hardcoded to + # match the check in Core/FormatEntity.cpp in the function FormatEntity::Format() for + # the Entry::Type::ThreadID case of the switch statement. + if self.getPlatform() == "linux" or self.getPlatform() == "freebsd": + tidstr = "tid = %u" % thread.GetThreadID() + else: + tidstr = "tid = 0x%4.4x" % thread.GetThreadID() + self.expect(thr, "Thread looks good with stop reason = breakpoint", exe=False, + substrs = [tidstr]) + + # The breakpoint should have a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # The breakpoint should be resolved by now. + bp = str(breakpoint) + self.expect(bp, "Breakpoint looks good and is resolved", exe=False, + substrs = ["file = 'main.c'", + "line = %d" % self.line, + "locations = 1"]) + + # Sanity check the print representation of frame. + frame = thread.GetFrameAtIndex(0) + frm = str(frame) + self.expect(frm, + "Frame looks good with correct index %d" % frame.GetFrameID(), + exe=False, + substrs = ["#%d" % frame.GetFrameID()]) + + # Lookup the "strings" string array variable and sanity check its print + # representation. + variable = frame.FindVariable("strings") + var = str(variable) + self.expect(var, "Variable for 'strings' looks good with correct name", exe=False, + substrs = ["%s" % variable.GetName()]) + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 4, + "Variable 'strings' should have 4 children") + + child3 = variable.GetChildAtIndex(3) + self.DebugSBValue(child3) + self.assertTrue(child3.GetSummary() == '"Guten Tag"', + 'strings[3] == "Guten Tag"') + + # Lookup the "char_16" char array variable. + variable = frame.FindVariable("char_16") + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 16, + "Variable 'char_16' should have 16 children") + + # Lookup the "ushort_matrix" ushort[] array variable. + # Notice the pattern of int(child0_2.GetValue(), 0). We pass a + # base of 0 so that the proper radix is determined based on the contents + # of the string. Same applies to long(). + variable = frame.FindVariable("ushort_matrix") + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 2, + "Variable 'ushort_matrix' should have 2 children") + child0 = variable.GetChildAtIndex(0) + self.DebugSBValue(child0) + self.assertTrue(child0.GetNumChildren() == 3, + "Variable 'ushort_matrix[0]' should have 3 children") + child0_2 = child0.GetChildAtIndex(2) + self.DebugSBValue(child0_2) + self.assertTrue(int(child0_2.GetValue(), 0) == 3, + "ushort_matrix[0][2] == 3") + + # Lookup the "long_6" char array variable. + variable = frame.FindVariable("long_6") + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 6, + "Variable 'long_6' should have 6 children") + child5 = variable.GetChildAtIndex(5) + self.DebugSBValue(child5) + self.assertTrue(int(child5.GetValue(), 0) == 6, + "long_6[5] == 6") + + # Last, check that "long_6" has a value type of eValueTypeVariableLocal + # and "argc" has eValueTypeVariableArgument. + from lldbsuite.test.lldbutil import value_type_to_str + self.assertTrue(variable.GetValueType() == lldb.eValueTypeVariableLocal, + "Variable 'long_6' should have '%s' value type." % + value_type_to_str(lldb.eValueTypeVariableLocal)) + argc = frame.FindVariable("argc") + self.DebugSBValue(argc) + self.assertTrue(argc.GetValueType() == lldb.eValueTypeVariableArgument, + "Variable 'argc' should have '%s' value type." % + value_type_to_str(lldb.eValueTypeVariableArgument)) diff --git a/packages/Python/lldbsuite/test/lang/c/array_types/cmds.txt b/packages/Python/lldbsuite/test/lang/c/array_types/cmds.txt new file mode 100644 index 0000000..8feebe2 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/array_types/cmds.txt @@ -0,0 +1,3 @@ +break main.c:42 +continue +var diff --git a/packages/Python/lldbsuite/test/lang/c/array_types/main.c b/packages/Python/lldbsuite/test/lang/c/array_types/main.c new file mode 100644 index 0000000..5f0680a --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/array_types/main.c @@ -0,0 +1,51 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +int main (int argc, char const *argv[]) +{ + struct point_tag { + int x; + int y; + }; + + struct rect_tag { + struct point_tag bottom_left; + struct point_tag top_right; + }; + char char_16[16] = "Hello World\n"; + char *strings[] = { "Hello", "Hola", "Bonjour", "Guten Tag" }; + char char_matrix[3][3] = {{'a', 'b', 'c' }, {'d', 'e', 'f' }, {'g', 'h', 'i' }}; + char char_matrix_matrix[3][2][3] = + { {{'a', 'b', 'c' }, {'d', 'e', 'f' }}, + {{'A', 'B', 'C' }, {'D', 'E', 'F' }}, + {{'1', '2', '3' }, {'4', '5', '6' }}}; + short short_4[4] = { 1,2,3,4 }; + short short_matrix[1][2] = { {1,2} }; + unsigned short ushort_4[4] = { 1,2,3,4 }; + unsigned short ushort_matrix[2][3] = { + { 1, 2, 3}, + {11,22,33} + }; + int int_2[2] = { 1, 2 }; + unsigned int uint_2[2] = { 1, 2 }; + long long_6[6] = { 1, 2, 3, 4, 5, 6 }; + unsigned long ulong_6[6] = { 1, 2, 3, 4, 5, 6 }; + struct point_tag points_2[2] = { + {1,2}, + {3,4} + }; + struct point_tag points_2_4_matrix[2][4] = { // Set break point at this line. + {{ 1, 2}, { 3, 4}, { 5, 6}, { 7, 8}}, + {{11,22}, {33,44}, {55,66}, {77,88}} + }; + struct rect_tag rects_2[2] = { + {{1,2}, {3,4}}, + {{5,6}, {7,8}} + }; + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/bitfields/Makefile b/packages/Python/lldbsuite/test/lang/c/bitfields/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/bitfields/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py b/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py new file mode 100644 index 0000000..de7a333 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py @@ -0,0 +1,162 @@ +"""Show bitfields and check that they display correctly.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class BitfieldsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + @skipIfWindows # BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800) + def test_and_run_command(self): + """Test 'frame variable ...' on a variable with bitfields.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # This should display correctly. + self.expect("frame variable --show-types bits", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(uint32_t:1) b1 = 1', + '(uint32_t:2) b2 = 3', + '(uint32_t:3) b3 = 7', + '(uint32_t) b4 = 15', + '(uint32_t:5) b5 = 31', + '(uint32_t:6) b6 = 63', + '(uint32_t:7) b7 = 127', + '(uint32_t:4) four = 15']) + + # And so should this. + # rdar://problem/8348251 + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(uint32_t:1) b1 = 1', + '(uint32_t:2) b2 = 3', + '(uint32_t:3) b3 = 7', + '(uint32_t) b4 = 15', + '(uint32_t:5) b5 = 31', + '(uint32_t:6) b6 = 63', + '(uint32_t:7) b7 = 127', + '(uint32_t:4) four = 15']) + + self.expect("expr (bits.b1)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '1']) + self.expect("expr (bits.b2)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '3']) + self.expect("expr (bits.b3)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '7']) + self.expect("expr (bits.b4)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '15']) + self.expect("expr (bits.b5)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '31']) + self.expect("expr (bits.b6)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '63']) + self.expect("expr (bits.b7)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '127']) + self.expect("expr (bits.four)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '15']) + + self.expect("frame variable --show-types more_bits", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(uint32_t:3) a = 3', + '(uint8_t:1) b = \'\\0\'', + '(uint8_t:1) c = \'\\x01\'', + '(uint8_t:1) d = \'\\0\'']) + + self.expect("expr (more_bits.a)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint32_t', '3']) + self.expect("expr (more_bits.b)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint8_t', '\\0']) + self.expect("expr (more_bits.c)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint8_t', '\\x01']) + self.expect("expr (more_bits.d)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['uint8_t', '\\0']) + + @add_test_categories(['pyapi']) + @skipIfWindows # BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800) + def test_and_python_api(self): + """Use Python APIs to inspect a bitfields variable.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread = target.GetProcess().GetThreadAtIndex(0) + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + from lldbsuite.test.lldbutil import stop_reason_to_str + self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % + stop_reason_to_str(thread.GetStopReason())) + + # The breakpoint should have a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + # Lookup the "bits" variable which contains 8 bitfields. + frame = thread.GetFrameAtIndex(0) + bits = frame.FindVariable("bits") + self.DebugSBValue(bits) + self.assertTrue(bits.GetTypeName() == 'Bits', "bits.GetTypeName() == 'Bits'"); + self.assertTrue(bits.GetNumChildren() == 10, "bits.GetNumChildren() == 10"); + test_compiler = self.getCompiler() + self.assertTrue(bits.GetByteSize() == 32, "bits.GetByteSize() == 32"); + + # Notice the pattern of int(b1.GetValue(), 0). We pass a base of 0 + # so that the proper radix is determined based on the contents of the + # string. + b1 = bits.GetChildMemberWithName("b1") + self.DebugSBValue(b1) + self.assertTrue(b1.GetName() == "b1" and + b1.GetTypeName() == "uint32_t:1" and + b1.IsInScope() and + int(b1.GetValue(), 0) == 1, + 'bits.b1 has type uint32_t:1, is in scope, and == 1') + + b7 = bits.GetChildMemberWithName("b7") + self.DebugSBValue(b7) + self.assertTrue(b7.GetName() == "b7" and + b7.GetTypeName() == "uint32_t:7" and + b7.IsInScope() and + int(b7.GetValue(), 0) == 127, + 'bits.b7 has type uint32_t:7, is in scope, and == 127') + + four = bits.GetChildMemberWithName("four") + self.DebugSBValue(four) + self.assertTrue(four.GetName() == "four" and + four.GetTypeName() == "uint32_t:4" and + four.IsInScope() and + int(four.GetValue(), 0) == 15, + 'bits.four has type uint32_t:4, is in scope, and == 15') + + # Now kill the process, and we are done. + rc = target.GetProcess().Kill() + self.assertTrue(rc.Success()) diff --git a/packages/Python/lldbsuite/test/lang/c/bitfields/main.c b/packages/Python/lldbsuite/test/lang/c/bitfields/main.c new file mode 100644 index 0000000..26c0176 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/bitfields/main.c @@ -0,0 +1,67 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdint.h> +#include <stdio.h> +int main (int argc, char const *argv[]) +{ + struct Bits + { + uint32_t : 1, // Unnamed bitfield + b1 : 1, + b2 : 2, + : 2, // Unnamed bitfield + b3 : 3, + : 2, // Unnamed bitfield (this will get removed) + b4 __attribute__ ((aligned(16))), + b5 : 5, + b6 : 6, + b7 : 7, + four : 4; + }; + + printf("%lu", sizeof(struct Bits)); + + struct Bits bits; + int i; + for (i=0; i<(1<<1); i++) + bits.b1 = i; //// break $source:$line + for (i=0; i<(1<<2); i++) + bits.b2 = i; //// break $source:$line + for (i=0; i<(1<<3); i++) + bits.b3 = i; //// break $source:$line + for (i=0; i<(1<<4); i++) + bits.b4 = i; //// break $source:$line + for (i=0; i<(1<<5); i++) + bits.b5 = i; //// break $source:$line + for (i=0; i<(1<<6); i++) + bits.b6 = i; //// break $source:$line + for (i=0; i<(1<<7); i++) + bits.b7 = i; //// break $source:$line + for (i=0; i<(1<<4); i++) + bits.four = i; //// break $source:$line + + struct MoreBits + { + uint32_t a : 3; + uint8_t : 1; + uint8_t b : 1; + uint8_t c : 1; + uint8_t d : 1; + }; + + struct MoreBits more_bits; + + more_bits.a = 3; + more_bits.b = 0; + more_bits.c = 1; + more_bits.d = 0; + + return 0; //// Set break point at this line. + +} diff --git a/packages/Python/lldbsuite/test/lang/c/blocks/Makefile b/packages/Python/lldbsuite/test/lang/c/blocks/Makefile new file mode 100644 index 0000000..752b7ae --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/blocks/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -fblocks + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py b/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py new file mode 100644 index 0000000..8f1c3be --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py @@ -0,0 +1,61 @@ +"""Test that lldb can invoke blocks and access variables inside them""" + +from __future__ import print_function + + + +import unittest2 +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class BlocksTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + lines = [] + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break at. + self.lines.append(line_number('main.c', '// Set breakpoint 0 here.')) + self.lines.append(line_number('main.c', '// Set breakpoint 1 here.')) + + @unittest2.expectedFailure("rdar://problem/10413887 - Call blocks in expressions") + def test_expr(self): + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + self.is_started = False + + # Break inside the foo function which takes a bar_ptr argument. + for line in self.lines: + lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True) + + self.wait_for_breakpoint() + + self.expect("expression a + b", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 7"]) + + self.expect("expression c", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 1"]) + + self.wait_for_breakpoint() + + # This should display correctly. + self.expect("expression (int)neg (-12)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["= 12"]) + + def wait_for_breakpoint(self): + if self.is_started == False: + self.is_started = True + self.runCmd("process launch", RUN_SUCCEEDED) + else: + self.runCmd("process continue", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) diff --git a/packages/Python/lldbsuite/test/lang/c/blocks/main.c b/packages/Python/lldbsuite/test/lang/c/blocks/main.c new file mode 100644 index 0000000..415e6c6 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/blocks/main.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int c = 1; + + int (^add)(int, int) = ^int(int a, int b) + { + return a + b + c; // Set breakpoint 0 here. + }; + + int (^neg)(int) = ^int(int a) + { + return -a; + }; + + printf("%d\n", add(3, 4)); + printf("%d\n", neg(-5)); // Set breakpoint 1 here. + + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/const_variables/Makefile b/packages/Python/lldbsuite/test/lang/c/const_variables/Makefile new file mode 100644 index 0000000..51adad1 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/const_variables/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +C_SOURCES := main.c functions.c + +CFLAGS_EXTRAS += -O3 + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py b/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py new file mode 100644 index 0000000..a112b2a --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py @@ -0,0 +1,64 @@ +"""Check that compiler-generated constant values work correctly""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class ConstVariableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + oslist=["freebsd", "linux"], + compiler="clang", compiler_version=["<", "3.5"]) + @expectedFailureAll( + oslist=["freebsd", "linux"], + compiler="clang", compiler_version=["=", "3.7"]) + @expectedFailureAll( + oslist=["freebsd", "linux"], + compiler="clang", compiler_version=["=", "3.8"]) + @expectedFailureAll(oslist=["freebsd", "linux"], compiler="icc") + @expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el']) + @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows") + @expectedFailureWindows("llvm.org/pr24490: We shouldn't be using platform-specific names like `getpid` in tests") + def test_and_run_command(self): + """Test interpreted and JITted expressions on constant values.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=1) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + self.runCmd("next") + self.runCmd("next") + + # Try frame variable. + self.expect("frame variable index", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(int32_t) index = 512']) + + # Try an interpreted expression. + self.expect("expr (index + 512)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['1024']) + + # Try a JITted expression. + self.expect("expr (int)getpid(); (index - 256)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['256']) + + self.runCmd("kill") diff --git a/packages/Python/lldbsuite/test/lang/c/const_variables/functions.c b/packages/Python/lldbsuite/test/lang/c/const_variables/functions.c new file mode 100644 index 0000000..c9ea638 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/const_variables/functions.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +void foo() +{ + printf("foo()\n"); +} + +int bar() +{ + int ret = 3; + printf("bar()->%d\n", ret); + return ret; +} + +void baaz(int i) +{ + printf("baaz(%d)\n", i); +} diff --git a/packages/Python/lldbsuite/test/lang/c/const_variables/main.c b/packages/Python/lldbsuite/test/lang/c/const_variables/main.c new file mode 100644 index 0000000..50a924e --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/const_variables/main.c @@ -0,0 +1,23 @@ +#include <stdint.h> +#include <stdio.h> + +extern int foo(); +extern int bar(); +extern int baaz(int i); + +int main() +{ + int32_t index; + + foo(); + + index = 512; + + if (bar()) + { + printf("COMPILER PLEASE STOP HERE\n"); + index = 256; + } + + baaz(index); +} diff --git a/packages/Python/lldbsuite/test/lang/c/enum_types/Makefile b/packages/Python/lldbsuite/test/lang/c/enum_types/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/enum_types/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py b/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py new file mode 100644 index 0000000..b0c5c88 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py @@ -0,0 +1,71 @@ +"""Look up enum type information and check for correct display.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class EnumTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test(self): + """Test 'image lookup -t days' and check for correct display and enum value printing.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + bkpt_id = lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # Look up information about the 'days' enum type. + # Check for correct display. + self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs = ['enum days {', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '}']) + + enum_values = [ '-4', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '5']; + + bkpt = self.target().FindBreakpointByID(bkpt_id) + for enum_value in enum_values: + self.expect("frame variable day", 'check for valid enumeration value', + substrs = [enum_value]) + lldbutil.continue_to_breakpoint (self.process(), bkpt) diff --git a/packages/Python/lldbsuite/test/lang/c/enum_types/main.c b/packages/Python/lldbsuite/test/lang/c/enum_types/main.c new file mode 100644 index 0000000..3d59654 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/enum_types/main.c @@ -0,0 +1,29 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int main (int argc, char const *argv[]) +{ + enum days { + Monday = -3, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, + kNumDays + }; + enum days day; + for (day = Monday - 1; day <= kNumDays + 1; day++) + { + printf("day as int is %i\n", (int)day); // Set break point at this line. + } + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/forward/Makefile b/packages/Python/lldbsuite/test/lang/c/forward/Makefile new file mode 100644 index 0000000..1db43ab --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/forward/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c foo.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/forward/README.txt b/packages/Python/lldbsuite/test/lang/c/forward/README.txt new file mode 100644 index 0000000..b7b66f7 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/forward/README.txt @@ -0,0 +1,5 @@ +This example has a function call in foo.c named "foo" that takes a forward +declaration to "struct bar" and uses it as a pointer argument. In main.c +we have a real declaration for "struct bar". We want to be able to find the +real definition of "struct bar" when we are stopped in foo in foo.c such that +when we stop in "foo" we see the contents of the "bar_ptr". diff --git a/packages/Python/lldbsuite/test/lang/c/forward/TestForwardDeclaration.py b/packages/Python/lldbsuite/test/lang/c/forward/TestForwardDeclaration.py new file mode 100644 index 0000000..33c0de2 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/forward/TestForwardDeclaration.py @@ -0,0 +1,47 @@ +"""Test that forward declaration of a data structure gets resolved correctly.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class ForwardDeclarationTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_and_run_command(self): + """Display *bar_ptr when stopped on a function with forward declaration of struct bar.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_symbol (self, "foo", num_expected_locations=1, sym_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # This should display correctly. + # Note that the member fields of a = 1 and b = 2 is by design. + self.expect("frame variable --show-types *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(bar) *bar_ptr = ', + '(int) a = 1', + '(int) b = 2']) + + # And so should this. + self.expect("expression --show-types -- *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(bar)', + '(int) a = 1', + '(int) b = 2']) diff --git a/packages/Python/lldbsuite/test/lang/c/forward/foo.c b/packages/Python/lldbsuite/test/lang/c/forward/foo.c new file mode 100644 index 0000000..2e050e7 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/forward/foo.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#include "foo.h" + +int +foo (struct bar *bar_ptr) +{ + return printf ("bar_ptr = %p\n", bar_ptr); +} diff --git a/packages/Python/lldbsuite/test/lang/c/forward/foo.h b/packages/Python/lldbsuite/test/lang/c/forward/foo.h new file mode 100644 index 0000000..3040927 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/forward/foo.h @@ -0,0 +1,4 @@ + +struct bar; + +int foo (struct bar *bar_ptr); diff --git a/packages/Python/lldbsuite/test/lang/c/forward/main.c b/packages/Python/lldbsuite/test/lang/c/forward/main.c new file mode 100644 index 0000000..6f9787c --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/forward/main.c @@ -0,0 +1,18 @@ +#include <stdio.h> +#include "foo.h" + +struct bar +{ + int a; + int b; +}; + +int +main (int argc, char const *argv[]) +{ + struct bar b= { 1, 2 }; + + foo (&b); + + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/function_types/Makefile b/packages/Python/lldbsuite/test/lang/c/function_types/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/function_types/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py b/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py new file mode 100644 index 0000000..2f9f1d1 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py @@ -0,0 +1,76 @@ +"""Test variable with function ptr type and that break on the function works.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class FunctionTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test(self): + """Test 'callback' has function ptr type, then break on the function.""" + self.build() + self.runToBreakpoint() + + # Check that the 'callback' variable display properly. + self.expect("frame variable --show-types callback", VARIABLES_DISPLAYED_CORRECTLY, + startstr = '(int (*)(const char *)) callback =') + + # And that we can break on the callback function. + lldbutil.run_break_set_by_symbol (self, "string_not_empty", num_expected_locations=1, sym_exact=True) + self.runCmd("continue") + + # Check that we do indeed stop on the string_not_empty function. + self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['a.out`string_not_empty', + 'stop reason = breakpoint']) + + @expectedFailureWindows("llvm.org/pr21765") + def test_pointers(self): + """Test that a function pointer to 'printf' works and can be called.""" + self.build() + self.runToBreakpoint() + + self.expect("expr string_not_empty", + substrs = ['(int (*)(const char *)) $0 = ', '(a.out`']) + + if self.platformIsDarwin(): + regexps = ['lib.*\.dylib`printf'] + else: + regexps = ['printf'] + self.expect("expr (int (*)(const char*, ...))printf", + substrs = ['(int (*)(const char *, ...)) $1 = '], + patterns = regexps) + + self.expect("expr $1(\"Hello world\\n\")", + startstr = '(int) $2 = 12') + + def runToBreakpoint(self): + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) diff --git a/packages/Python/lldbsuite/test/lang/c/function_types/main.c b/packages/Python/lldbsuite/test/lang/c/function_types/main.c new file mode 100644 index 0000000..8be3c4d --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/function_types/main.c @@ -0,0 +1,22 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int string_not_empty (const char *s) +{ + if (s && s[0]) + return 1; + return 0; +} + +int main (int argc, char const *argv[]) +{ + int (*callback)(const char *) = string_not_empty; + + return callback(0); // Set break point at this line. +} diff --git a/packages/Python/lldbsuite/test/lang/c/global_variables/Makefile b/packages/Python/lldbsuite/test/lang/c/global_variables/Makefile new file mode 100644 index 0000000..b1b77da --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/global_variables/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +DYLIB_NAME := a +DYLIB_C_SOURCES := a.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py b/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py new file mode 100644 index 0000000..1f91cd1 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py @@ -0,0 +1,76 @@ +"""Show global variables and check that they do indeed have global scopes.""" + +from __future__ import print_function + + +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class GlobalVariablesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number(self.source, '// Set break point at this line.') + self.shlib_names = ["a"] + + @expectedFailureWindows("llvm.org/pr24764") + @expectedFailureAll("llvm.org/pr25872", oslist=["macosx"], debug_info="dwarf") + def test_c_global_variables(self): + """Test 'frame variable --scope --no-args' which omits args and shows scopes.""" + self.build() + + # Create a target by the debugger. + target = self.dbg.CreateTarget("a.out") + self.assertTrue(target, VALID_TARGET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get automatically uploaded + environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # Check that GLOBAL scopes are indicated for the variables. + self.expect("frame variable --show-types --scope --show-globals --no-args", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['GLOBAL: (int) g_file_global_int = 42', + 'STATIC: (const int) g_file_static_int = 2', + 'GLOBAL: (const char *) g_file_global_cstr', + '"g_file_global_cstr"', + 'STATIC: (const char *) g_file_static_cstr', + '"g_file_static_cstr"', + 'GLOBAL: (int) g_common_1 = 21']) + + # 'frame variable' should support address-of operator. + self.runCmd("frame variable &g_file_global_int") + + # Exercise the 'target variable' command to display globals in a.c file. + self.expect("target variable g_a", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['g_a', '123']) + self.expect("target variable g_marked_spot.x", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['g_marked_spot.x', '20']) + + # rdar://problem/9747668 + # runCmd: target variable g_marked_spot.y + # output: (int) g_marked_spot.y = <a.o[0x214] can't be resolved, in not currently loaded. + # > + self.expect("target variable g_marked_spot.y", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['g_marked_spot.y', '21']) + self.expect("target variable g_marked_spot.y", VARIABLES_DISPLAYED_CORRECTLY, matching=False, + substrs = ["can't be resolved"]) diff --git a/packages/Python/lldbsuite/test/lang/c/global_variables/a.c b/packages/Python/lldbsuite/test/lang/c/global_variables/a.c new file mode 100644 index 0000000..d169d5d --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/global_variables/a.c @@ -0,0 +1,15 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +int g_a = 123; +struct Point { + int x; + int y; +}; +struct Point g_marked_spot = { 20, 21 }; + diff --git a/packages/Python/lldbsuite/test/lang/c/global_variables/cmds.txt b/packages/Python/lldbsuite/test/lang/c/global_variables/cmds.txt new file mode 100644 index 0000000..6906a07 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/global_variables/cmds.txt @@ -0,0 +1,3 @@ +break main.c:5 +continue +var -global g_a -global g_global_int diff --git a/packages/Python/lldbsuite/test/lang/c/global_variables/main.c b/packages/Python/lldbsuite/test/lang/c/global_variables/main.c new file mode 100644 index 0000000..499b250 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/global_variables/main.c @@ -0,0 +1,24 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int g_common_1; // Not initialized on purpose to cause it to be undefined external in .o file +int g_file_global_int = 42; +static const int g_file_static_int = 2; +const char *g_file_global_cstr = "g_file_global_cstr"; +static const char *g_file_static_cstr = "g_file_static_cstr"; + +extern int g_a; +int main (int argc, char const *argv[]) +{ + g_common_1 = g_file_global_int / g_file_static_int; + static const char *g_func_static_cstr = "g_func_static_cstr"; + printf ("%s %s\n", g_file_global_cstr, g_file_static_cstr); + return g_file_global_int + g_a + g_common_1; // Set break point at this line. //// break $source:$line; continue; var -global g_a -global g_global_int +} diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/Makefile b/packages/Python/lldbsuite/test/lang/c/inlines/Makefile new file mode 100644 index 0000000..c5b0d18 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/inlines/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := inlines.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/inlines.c b/packages/Python/lldbsuite/test/lang/c/inlines/inlines.c new file mode 100644 index 0000000..1e920f1 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/inlines/inlines.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include "inlines.h" + +#define INLINE_ME __inline__ __attribute__((always_inline)) + +int +not_inlined_2 (int input) +{ + printf ("Called in not_inlined_2 with : %d.\n", input); + return input; +} + +int +not_inlined_1 (int input) +{ + printf ("Called in not_inlined_1 with %d.\n", input); + return not_inlined_2(input); +} + +INLINE_ME int +inner_inline (int inner_input, int mod_value) +{ + int inner_result; + inner_result = inner_input % mod_value; + printf ("Returning: %d.\n", inner_result); + return not_inlined_1 (inner_result); +} + +INLINE_ME int +outer_inline (int outer_input) +{ + int outer_result; + + outer_result = inner_inline (outer_input, outer_input % 3); + return outer_result; +} + +int +main (int argc, char **argv) +{ + printf ("Starting...\n"); + + int (*func_ptr) (int); + func_ptr = outer_inline; + + outer_inline (argc); + + func_ptr (argc); + + return 0; +} + + diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/inlines.h b/packages/Python/lldbsuite/test/lang/c/inlines/inlines.h new file mode 100644 index 0000000..265d7b4 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/inlines/inlines.h @@ -0,0 +1,4 @@ +int inner_inline (int inner_input, int mod_value); +int outer_inline (int outer_input); +int not_inlined_2 (int input); +int not_inlined_1 (int input); diff --git a/packages/Python/lldbsuite/test/lang/c/modules/Makefile b/packages/Python/lldbsuite/test/lang/c/modules/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/modules/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py b/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py new file mode 100644 index 0000000..cd31f9d --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py @@ -0,0 +1,65 @@ +"""Test that importing modules in C works as expected.""" + +from __future__ import print_function + + + +import os, time +import lldb +import platform +import lldbsuite.test.lldbutil as lldbutil + +from distutils.version import StrictVersion + +from lldbsuite.test.lldbtest import * + +class CModulesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfFreeBSD + @expectedFailureDarwin('http://llvm.org/pr24302') + @expectedFailureLinux('http://llvm.org/pr23456') # 'fopen' has unknown return type + @expectedFailureWindows("llvm.org/pr24489: Name lookup not working correctly on Windows") + def test_expr(self): + if platform.system() == "Darwin" and platform.release() < StrictVersion('12.0.0'): + self.skipTest() + + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + self.expect("expr @import Darwin; 3", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["int", "3"]) + + self.expect("expr *fopen(\"/dev/zero\", \"w\")", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["FILE", "_close", "__sclose"]) + + self.expect("expr *myFile", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["a", "5", "b", "9"]) + + self.expect("expr MIN((uint64_t)2, (uint64_t)3)", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["uint64_t", "2"]) + + self.expect("expr stdin", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(FILE *)", "0x"]) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set breakpoint 0 here.') diff --git a/packages/Python/lldbsuite/test/lang/c/modules/main.c b/packages/Python/lldbsuite/test/lang/c/modules/main.c new file mode 100644 index 0000000..2b244bc --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/modules/main.c @@ -0,0 +1,20 @@ +#include <stdlib.h> + +int printf(const char * __restrict format, ...); + +typedef struct { + int a; + int b; +} FILE; + +int main() +{ + FILE *myFile = malloc(sizeof(FILE)); + + myFile->a = 5; + myFile->b = 9; + + printf("%d\n", myFile->a + myFile->b); // Set breakpoint 0 here. + + free(myFile); +} diff --git a/packages/Python/lldbsuite/test/lang/c/recurse/Makefile b/packages/Python/lldbsuite/test/lang/c/recurse/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/recurse/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/recurse/main.c b/packages/Python/lldbsuite/test/lang/c/recurse/main.c new file mode 100644 index 0000000..1159669 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/recurse/main.c @@ -0,0 +1,28 @@ +#include <stdint.h> +#include <stdio.h> + +uint32_t +recurse_crash (uint32_t depth) +{ + if (depth > 0) + return recurse_crash (depth - 1); + return 0; +} + +int +main (int argc, char const *argv[]) +{ + // If we have more than one argument, then it should a depth to recurse to. + // If we have just the program name as an argument, use UINT32_MAX so we + // eventually crash the program by overflowing the stack + uint32_t depth = UINT32_MAX; + if (argc > 1) + { + char *end = NULL; + depth = strtoul (argv[1], &end, 0); + if (end == NULL || *end != '\0') + depth = UINT32_MAX; + } + recurse_crash (depth); + return 0; +}
\ No newline at end of file diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile b/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile new file mode 100644 index 0000000..12e5561 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +C_SOURCES := test.c + +CFLAGS ?= -g -O1 + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py b/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py new file mode 100644 index 0000000..7ef1f24 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py @@ -0,0 +1,70 @@ +"""Check that compiler-generated register values work correctly""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class RegisterVariableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=['macosx'], compiler='clang', compiler_version=['<', '7.0.0'], debug_info="dsym") + @expectedFailureClang(None, ['<', '3.5']) + @expectedFailureGcc(None, ['is', '4.8.2']) + def test_and_run_command(self): + """Test expressions on register values.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_source_regexp(self, "break", num_expected_locations=2) + + #################### + # First breakpoint + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # Try some variables that should be visible + self.expect("expr a", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(int) $0 = 2']) + + self.expect("expr b->m1", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(int) $1 = 3']) + + ##################### + # Second breakpoint + + self.runCmd("continue") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # Try some variables that should be visible + self.expect("expr b->m2", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(int) $2 = 5']) + + self.expect("expr c", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['(int) $3 = 5']) + + self.runCmd("kill") diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/test.c b/packages/Python/lldbsuite/test/lang/c/register_variables/test.c new file mode 100644 index 0000000..e467ac4 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/register_variables/test.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +struct bar { + int m1; + int m2; +}; + +void f1(int a, struct bar *b) __attribute__ ((noinline)); +void f1(int a, struct bar *b) +{ + b->m2 = b->m1 + a; // set breakpoint here +} + +void f2(struct bar *b) __attribute__ ((noinline)); +void f2(struct bar *b) +{ + int c = b->m2; + printf("%d\n", c); // set breakpoint here +} + +int main() +{ + struct bar myBar = { 3, 4 }; + f1(2, &myBar); + f2(&myBar); + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/set_values/Makefile b/packages/Python/lldbsuite/test/lang/c/set_values/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/set_values/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py b/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py new file mode 100644 index 0000000..ab81024 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py @@ -0,0 +1,111 @@ +"""Test settings and readings of program variables.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class SetValuesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.line1 = line_number('main.c', '// Set break point #1.') + self.line2 = line_number('main.c', '// Set break point #2.') + self.line3 = line_number('main.c', '// Set break point #3.') + self.line4 = line_number('main.c', '// Set break point #4.') + self.line5 = line_number('main.c', '// Set break point #5.') + + @expectedFailureWindows("llvm.org/pr21765") + def test(self): + """Test settings and readings of program variables.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Set breakpoints on several places to set program variables. + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line1, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line2, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line3, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line4, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line5, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) + + # main.c:15 + # Check that 'frame variable --show-types' displays the correct data type and value. + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(char) i = 'a'") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 'b'") + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(char) i = 'b'") + + self.runCmd("continue") + + # main.c:36 + # Check that 'frame variable --show-types' displays the correct data type and value. + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + patterns = ["\((short unsigned int|unsigned short)\) i = 33"]) + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 333") + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + patterns = ["\((short unsigned int|unsigned short)\) i = 333"]) + + self.runCmd("continue") + + # main.c:57 + # Check that 'frame variable --show-types' displays the correct data type and value. + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(long) i = 33") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 33333") + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(long) i = 33333") + + self.runCmd("continue") + + # main.c:78 + # Check that 'frame variable --show-types' displays the correct data type and value. + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(double) i = 2.25") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 1.5") + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(double) i = 1.5") + + self.runCmd("continue") + + # main.c:85 + # Check that 'frame variable --show-types' displays the correct data type and value. + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(long double) i = 2.25") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 1.5") + self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY, + startstr = "(long double) i = 1.5") diff --git a/packages/Python/lldbsuite/test/lang/c/set_values/main.c b/packages/Python/lldbsuite/test/lang/c/set_values/main.c new file mode 100644 index 0000000..64f01a9 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/set_values/main.c @@ -0,0 +1,116 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +void set_char(void) +{ + char i = 'a'; + printf("before (char) i = %c\n", i); + printf("after (char) i = %c\n", i); // Set break point #1. //// break $source:$line +} + +void set_uchar(void) +{ + unsigned char i = 'a'; + printf("before (unsigned char) i = %c\n", i); + printf("after (unsigned char) i = %c\n", i); //// break $source:$line +} + +void set_short(void) +{ + short i = 33; + printf("before (short) i = %i\n", i); + printf("after (short) i = %i\n", i); //// break $source:$line +} + +void set_ushort(void) +{ + unsigned short i = 33; + printf("before (unsigned short) i = %i\n", i); + printf("after (unsigned short) i = %i\n", i); // Set break point #2. //// break $source:$line +} + +void set_int(void) +{ + int i = 33; + printf("before (int) i = %i\n", i); + printf("after (int) i = %i\n", i); //// break $source:$line +} + +void set_uint(void) +{ + unsigned int i = 33; + printf("before (unsigned int) i = %u\n", i); + printf("after (unsigned int) i = %u\n", i); //// break $source:$line +} + +void set_long(void) +{ + long i = 33; + printf("before (long) i = %li\n", i); + printf("after (long) i = %li\n", i); // Set break point #3. //// break $source:$line +} + +void set_ulong(void) +{ + unsigned long i = 33; + printf("before (unsigned long) i = %lu\n", i); + printf("after (unsigned long) i = %lu\n", i); //// break $source:$line +} + +void set_float(void) +{ + float i = 2.25; + printf("before (float) i = %g\n", i); + printf("after (float) i = %g\n", i); //// break $source:$line +} + +void set_double(void) +{ + double i = 2.25; + printf("before (double) i = %g\n", i); + printf("after (double) i = %g\n", i); // Set break point #4. //// break $source:$line +} + +void set_long_double(void) +{ + long double i = 2.25; + printf("before (long double) i = %Lg\n", i); + printf("after (long double) i = %Lg\n", i); // Set break point #5. //// break $source:$line +} + +void set_point (void) +{ + struct point_tag { + int x; + int y; + }; + struct point_tag points_2[2] = { + {1,2}, + {3,4} + }; +} + +int main (int argc, char const *argv[]) +{ + // Continue to the breakpoint in set_char() + set_char(); //// continue; var i; val -set 99 1 + set_uchar(); //// continue; var i; val -set 99 2 + set_short(); //// continue; var i; val -set -42 3 + set_ushort(); //// continue; var i; val -set 42 4 + set_int(); //// continue; var i; val -set -42 5 + set_uint(); //// continue; var i; val -set 42 6 + set_long(); //// continue; var i; val -set -42 7 + set_ulong(); //// continue; var i; val -set 42 8 + set_float(); //// continue; var i; val -set 123.456 9 + set_double(); //// continue; var i; val -set 123.456 10 + set_long_double(); //// continue; var i; val -set 123.456 11 + set_point (); //// continue + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib/Makefile b/packages/Python/lldbsuite/test/lang/c/shared_lib/Makefile new file mode 100644 index 0000000..854002e --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib/Makefile @@ -0,0 +1,8 @@ +LEVEL = ../../../make + +DYLIB_NAME := foo +DYLIB_C_SOURCES := foo.c +C_SOURCES := main.c +CFLAGS_EXTRAS += -fPIC + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py b/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py new file mode 100644 index 0000000..954d1ba --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py @@ -0,0 +1,71 @@ +"""Test that types defined in shared libraries work correctly.""" + +from __future__ import print_function + + + +import unittest2 +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class SharedLibTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_expr(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): + self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") + + self.build() + self.common_setup() + + # This should display correctly. + self.expect("expression --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(foo)", "(sub_foo)", "other_element = 3"]) + + @unittest2.expectedFailure("rdar://problem/10704639") + def test_frame_variable(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + self.build() + self.common_setup() + + # This should display correctly. + self.expect("frame variable --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(foo)", "(sub_foo)", "other_element = 3"]) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number(self.source, '// Set breakpoint 0 here.') + self.shlib_names = ["foo"] + + def common_setup(self): + # Run in synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget("a.out") + self.assertTrue(target, VALID_TARGET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get automatically uploaded + environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.c b/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.c new file mode 100644 index 0000000..6431bc4 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.c @@ -0,0 +1,22 @@ +#include "foo.h" +#include <stdlib.h> + +struct foo +{ + struct sub_foo sub_element; + int other_element; +}; + +struct foo * +GetMeAFoo() +{ + struct foo *ret_val = (struct foo *) malloc (sizeof (struct foo)); + ret_val->other_element = 3; + return ret_val; +} + +struct sub_foo * +GetMeASubFoo (struct foo *in_foo) +{ + return &(in_foo->sub_element); +} diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.h b/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.h new file mode 100644 index 0000000..78b9e3f --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.h @@ -0,0 +1,10 @@ +struct foo; + +struct sub_foo +{ + int sub_1; + char *sub_2; +}; + +LLDB_TEST_API struct foo *GetMeAFoo(); +LLDB_TEST_API struct sub_foo *GetMeASubFoo(struct foo *in_foo); diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib/main.c b/packages/Python/lldbsuite/test/lang/c/shared_lib/main.c new file mode 100644 index 0000000..b4377de --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib/main.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include "foo.h" + +int +main () +{ + struct foo *my_foo_ptr; + my_foo_ptr = GetMeAFoo(); + + printf ("My sub foo has: %d.\n", GetMeASubFoo(my_foo_ptr)->sub_1); // Set breakpoint 0 here. + + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/Makefile b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/Makefile new file mode 100644 index 0000000..51347d7 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/Makefile @@ -0,0 +1,10 @@ +LEVEL = ../../../make + +DYLIB_NAME := foo +DYLIB_C_SOURCES := foo.c +C_SOURCES := main.c +CFLAGS_EXTRAS += -fPIC + +SPLIT_DEBUG_SYMBOLS = YES + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py new file mode 100644 index 0000000..a9cb46c --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py @@ -0,0 +1,73 @@ +"""Test that types defined in shared libraries with stripped symbols work correctly.""" + +from __future__ import print_function + + + +import unittest2 +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class SharedLibStrippedTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows # Test crashes + def test_expr(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): + self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") + + self.build() + self.common_setup() + + # This should display correctly. + self.expect("expression --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(foo)", "(sub_foo)", "other_element = 3"]) + + @expectedFailureWindows # Test crashes + @unittest2.expectedFailure("rdar://problem/10381325") + def test_frame_variable(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + self.build() + self.common_setup() + + # This should display correctly. + self.expect("frame variable --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["(foo)", "(sub_foo)", "other_element = 3"]) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number(self.source, '// Set breakpoint 0 here.') + self.shlib_names = ["foo"] + + def common_setup(self): + # Run in synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget("a.out") + self.assertTrue(target, VALID_TARGET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line (self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get automatically uploaded + environment = self.registerSharedLibrariesWithTarget(target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # The breakpoint should have a hit count of 1. + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs = [' resolved, hit count = 1']) diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.c b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.c new file mode 100644 index 0000000..6431bc4 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.c @@ -0,0 +1,22 @@ +#include "foo.h" +#include <stdlib.h> + +struct foo +{ + struct sub_foo sub_element; + int other_element; +}; + +struct foo * +GetMeAFoo() +{ + struct foo *ret_val = (struct foo *) malloc (sizeof (struct foo)); + ret_val->other_element = 3; + return ret_val; +} + +struct sub_foo * +GetMeASubFoo (struct foo *in_foo) +{ + return &(in_foo->sub_element); +} diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.h b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.h new file mode 100644 index 0000000..78b3c12 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.h @@ -0,0 +1,12 @@ +struct foo; + +struct sub_foo +{ + int sub_1; + char *sub_2; +}; + +struct foo *GetMeAFoo(); +struct sub_foo *GetMeASubFoo (struct foo *in_foo); + + diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/main.c b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/main.c new file mode 100644 index 0000000..b4377de --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/main.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include "foo.h" + +int +main () +{ + struct foo *my_foo_ptr; + my_foo_ptr = GetMeAFoo(); + + printf ("My sub foo has: %d.\n", GetMeASubFoo(my_foo_ptr)->sub_1); // Set breakpoint 0 here. + + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/stepping/Makefile b/packages/Python/lldbsuite/test/lang/c/stepping/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/stepping/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py b/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py new file mode 100644 index 0000000..c7a3de4 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py @@ -0,0 +1,242 @@ +"""Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + +from __future__ import print_function + + + +import os, time +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class TestCStepping(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def getCategories(self): + return ['basic_process'] + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + + @expectedFailureFreeBSD('llvm.org/pr17932') + @expectedFailureLinux # llvm.org/pr14437 + @expectedFailureWindows("llvm.org/pr24777") + @add_test_categories(['pyapi']) + def test_and_python_api(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec (self.main_source) + + breakpoints_to_disable = [] + + break_1_in_main = target.BreakpointCreateBySourceRegex ('// frame select 2, thread step-out while stopped at .c.1..', self.main_source_spec) + self.assertTrue(break_1_in_main, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_1_in_main) + + break_in_a = target.BreakpointCreateBySourceRegex ('// break here to stop in a before calling b', self.main_source_spec) + self.assertTrue(break_in_a, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_in_a) + + break_in_b = target.BreakpointCreateBySourceRegex ('// thread step-out while stopped at .c.2..', self.main_source_spec) + self.assertTrue(break_in_b, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_in_b) + + break_in_c = target.BreakpointCreateBySourceRegex ('// Find the line number of function .c. here.', self.main_source_spec) + self.assertTrue(break_in_c, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_in_c) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_1_in_main) + + if len(threads) != 1: + self.fail ("Failed to stop at first breakpoint in main.") + + thread = threads[0] + + # Get the stop id and for fun make sure it increases: + old_stop_id = process.GetStopID() + + # Now step over, which should cause us to hit the breakpoint in "a" + thread.StepOver() + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_a) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in a.") + + # Check that the stop ID increases: + new_stop_id = process.GetStopID() + self.assertTrue(new_stop_id > old_stop_id, "Stop ID increases monotonically.") + + thread = threads[0] + + # Step over, and we should hit the breakpoint in b: + thread.StepOver() + + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in b.") + thread = threads[0] + + # Now try running some function, and make sure that we still end up in the same place + # and with the same stop reason. + frame = thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + current_file = frame.GetLineEntry().GetFileSpec() + current_bp = [] + current_bp.append(thread.GetStopReasonDataAtIndex(0)) + current_bp.append(thread.GetStopReasonDataAtIndex(1)) + + stop_id_before_expression = process.GetStopID() + stop_id_before_including_expressions = process.GetStopID(True) + + frame.EvaluateExpression ("(int) printf (print_string)") + + frame = thread.GetFrameAtIndex(0) + self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") + self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") + self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") + + # Also make sure running the expression didn't change the public stop id + # but did change if we are asking for expression stops as well. + stop_id_after_expression = process.GetStopID() + stop_id_after_including_expressions = process.GetStopID(True) + + self.assertTrue (stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID") + + self.assertTrue (stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.") + + # Do the same thing with an expression that's going to crash, and make sure we are still unchanged. + + frame.EvaluateExpression ("((char *) 0)[0] = 'a'") + + frame = thread.GetFrameAtIndex(0) + self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") + self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") + self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") + + # Now continue and make sure we just complete the step: + # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the + # breakpoint a "b" and we don't want to hit that. + for bkpt in breakpoints_to_disable: + bkpt.SetEnabled(False) + + process.Continue() + + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "a") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # And one more time should get us back to main: + process.Continue() + + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # Now make sure we can call a function, break in the called function, then have "continue" get us back out again: + frame = thread.GetFrameAtIndex(0) + frame = thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + current_file = frame.GetLineEntry().GetFileSpec() + + break_in_b.SetEnabled(True) + frame.EvaluateExpression ("b (4)", lldb.eNoDynamicValues, False) + + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in b when calling b.") + thread = threads[0] + + # So do a step over here to make sure we can still do that: + + thread.StepOver() + + # See that we are still in b: + func_name = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertTrue (func_name == "b", "Should be in 'b', were in %s"%(func_name)) + + # Okay, now if we continue, we will finish off our function call and we should end up back in "a" as if nothing had happened: + process.Continue () + + self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == current_line) + self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec() == current_file) + + # Now we are going to test step in targeting a function: + + break_in_b.SetEnabled (False) + + break_before_complex_1 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targeting b.', self.main_source_spec) + self.assertTrue(break_before_complex_1, VALID_BREAKPOINT) + + break_before_complex_2 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targeting complex.', self.main_source_spec) + self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) + + break_before_complex_3 = target.BreakpointCreateBySourceRegex ('// Stop here to step targeting b and hitting breakpoint.', self.main_source_spec) + self.assertTrue(break_before_complex_3, VALID_BREAKPOINT) + + break_before_complex_4 = target.BreakpointCreateBySourceRegex ('// Stop here to make sure bogus target steps over.', self.main_source_spec) + self.assertTrue(break_before_complex_4, VALID_BREAKPOINT) + + threads = lldbutil.continue_to_breakpoint(process, break_before_complex_1) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_1.SetEnabled(False) + + thread.StepInto ("b") + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") + + # Now continue out and stop at the next call to complex. This time step all the way into complex: + threads = lldbutil.continue_to_breakpoint (process, break_before_complex_2) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_2.SetEnabled(False) + + thread.StepInto ("complex") + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "complex") + + # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targeting b: + threads = lldbutil.continue_to_breakpoint (process, break_before_complex_3) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_3.SetEnabled(False) + + break_at_start_of_a = target.BreakpointCreateByName ('a') + break_at_start_of_c = target.BreakpointCreateByName ('c') + + thread.StepInto ("b") + threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint); + + self.assertTrue (len(threads) == 1) + thread = threads[0] + stop_break_id = thread.GetStopReasonDataAtIndex(0) + self.assertTrue(stop_break_id == break_at_start_of_a.GetID() or stop_break_id == break_at_start_of_c.GetID()) + + break_at_start_of_a.SetEnabled(False) + break_at_start_of_c.SetEnabled(False) + + process.Continue() + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") + + # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targeting b: + threads = lldbutil.continue_to_breakpoint (process, break_before_complex_4) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_4.SetEnabled(False) + + thread.StepInto("NoSuchFunction") + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main") diff --git a/packages/Python/lldbsuite/test/lang/c/stepping/TestThreadStepping.py b/packages/Python/lldbsuite/test/lang/c/stepping/TestThreadStepping.py new file mode 100644 index 0000000..c3ed3f9 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/stepping/TestThreadStepping.py @@ -0,0 +1,81 @@ +""" +Test thread stepping features in combination with frame select. +""" + +from __future__ import print_function + + + +import os, time +import re +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class ThreadSteppingTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to of function 'c'. + self.line1 = line_number('main.c', '// Find the line number of function "c" here.') + self.line2 = line_number('main.c', '// frame select 2, thread step-out while stopped at "c(1)"') + self.line3 = line_number('main.c', '// thread step-out while stopped at "c(2)"') + self.line4 = line_number('main.c', '// frame select 1, thread step-out while stopped at "c(3)"') + + def test_step_out_with_run_command(self): + """Exercise thread step-out and frame select followed by thread step-out.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Create a breakpoint inside function 'c'. + lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line1, num_expected_locations=1, loc_exact=True) + + # Now run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The process should be stopped at this point. + self.expect("process status", PROCESS_STOPPED, + patterns = ['Process .* stopped']) + + # The frame #0 should correspond to main.c:32, the executable statement + # in function name 'c'. And frame #3 should point to main.c:37. + self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, + substrs = ["stop reason = breakpoint"], + patterns = ["frame #0.*main.c:%d" % self.line1, + "frame #3.*main.c:%d" % self.line2]) + + # We want to move the pc to frame #3. This can be accomplished by + # 'frame select 2', followed by 'thread step-out'. + self.runCmd("frame select 2") + self.runCmd("thread step-out") + self.expect("thread backtrace", STEP_OUT_SUCCEEDED, + substrs = ["stop reason = step out"], + patterns = ["frame #0.*main.c:%d" % self.line2]) + + # Let's move on to a single step-out case. + self.runCmd("process continue") + + # The process should be stopped at this point. + self.expect("process status", PROCESS_STOPPED, + patterns = ['Process .* stopped']) + self.runCmd("thread step-out") + self.expect("thread backtrace", STEP_OUT_SUCCEEDED, + substrs = ["stop reason = step out"], + patterns = ["frame #0.*main.c:%d" % self.line3]) + + # Do another frame selct, followed by thread step-out. + self.runCmd("process continue") + + # The process should be stopped at this point. + self.expect("process status", PROCESS_STOPPED, + patterns = ['Process .* stopped']) + self.runCmd("frame select 1") + self.runCmd("thread step-out") + self.expect("thread backtrace", STEP_OUT_SUCCEEDED, + substrs = ["stop reason = step out"], + patterns = ["frame #0.*main.c:%d" % self.line4]) diff --git a/packages/Python/lldbsuite/test/lang/c/stepping/main.c b/packages/Python/lldbsuite/test/lang/c/stepping/main.c new file mode 100644 index 0000000..d8b4a2d --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/stepping/main.c @@ -0,0 +1,69 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int a(int); +int b(int); +int c(int); +const char *print_string = "aaaaaaaaaa\n"; + +int a(int val) +{ + int return_value = val; // basic break at the start of b + + if (val <= 1) + { + return_value = b(val); // break here to stop in a before calling b + } + else if (val >= 3) + { + return_value = c(val); + } + + return return_value; +} + +int b(int val) +{ + int rc = c(val); // thread step-out while stopped at "c(2)" + return rc; +} + +int c(int val) +{ + return val + 3; // Find the line number of function "c" here. +} + +int complex (int first, int second, int third) +{ + return first + second + third; // Step in targeting complex should stop here +} + +int main (int argc, char const *argv[]) +{ + int A1 = a(1); // frame select 2, thread step-out while stopped at "c(1)" + printf("a(1) returns %d\n", A1); + + int B2 = b(2); + printf("b(2) returns %d\n", B2); + + int A3 = a(3); // frame select 1, thread step-out while stopped at "c(3)" + printf("a(3) returns %d\n", A3); + + int A4 = complex (a(1), b(2), c(3)); // Stop here to try step in targeting b. + + int A5 = complex (a(2), b(3), c(4)); // Stop here to try step in targeting complex. + + int A6 = complex (a(4), b(5), c(6)); // Stop here to step targeting b and hitting breakpoint. + + int A7 = complex (a(5), b(6), c(7)); // Stop here to make sure bogus target steps over. + + printf ("I am using print_string: %s.\n", print_string); + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/strings/Makefile b/packages/Python/lldbsuite/test/lang/c/strings/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/strings/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py b/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py new file mode 100644 index 0000000..6f2a9ff --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py @@ -0,0 +1,54 @@ +""" +Tests that C strings work as expected in expressions +""" +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class CStringsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureWindows("llvm.org/pr21765") + def test_with_run_command(self): + """Tests that C strings work as expected in expressions""" + self.build() + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + line = line_number('main.c', '// breakpoint 1') + lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- a[2]", + patterns = ["\((const )?char\) \$0 = 'c'"]) + + self.expect("expression -- z[2]", + startstr = "(const char) $1 = 'x'") + + # On Linux, the expression below will test GNU indirect function calls. + self.expect("expression -- (int)strlen(\"hello\")", + startstr = "(int) $2 = 5") + + self.expect("expression -- \"world\"[2]", + startstr = "(const char) $3 = 'r'") + + self.expect("expression -- \"\"[0]", + startstr = "(const char) $4 = '\\0'") + + self.expect("expr --raw -- \"hello\"", + substrs = ['[0] = \'h\'', + '[5] = \'\\0\'']) + + self.expect("p \"hello\"", + substrs = ['[6]) $', 'hello']) + + self.expect("p (char*)\"hello\"", + substrs = ['(char *) $', ' = 0x', + 'hello']) + + self.expect("p (int)strlen(\"\")", + substrs = ['(int) $', ' = 0']) + + self.expect("expression !z", + substrs = ['false']) diff --git a/packages/Python/lldbsuite/test/lang/c/strings/main.c b/packages/Python/lldbsuite/test/lang/c/strings/main.c new file mode 100644 index 0000000..e02580b --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/strings/main.c @@ -0,0 +1,18 @@ +//===-- main.c ----------------------------------------------------*- C -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +int main() +{ + const char a[] = "abcde"; + const char *z = "vwxyz"; + + printf("%s %s", a, z); // breakpoint 1 +} diff --git a/packages/Python/lldbsuite/test/lang/c/struct_types/Makefile b/packages/Python/lldbsuite/test/lang/c/struct_types/Makefile new file mode 100644 index 0000000..cd9ca5c --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/struct_types/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py b/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py new file mode 100644 index 0000000..87ad326 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py @@ -0,0 +1,4 @@ +import lldbsuite.test.lldbinline as lldbinline +import lldbsuite.test.lldbtest as lldbtest + +lldbinline.MakeInlineTest(__file__, globals(), [lldbtest.expectedFailureWindows("llvm.org/pr24764")] ) diff --git a/packages/Python/lldbsuite/test/lang/c/struct_types/main.c b/packages/Python/lldbsuite/test/lang/c/struct_types/main.c new file mode 100644 index 0000000..29ac10c --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/struct_types/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +struct things_to_sum { + int a; + int b; + int c; +}; + +int sum_things(struct things_to_sum tts) +{ + return tts.a + tts.b + tts.c; +} + +int main (int argc, char const *argv[]) +{ + struct point_tag { + int x; + int y; + char padding[0]; + }; //% self.expect("frame variable pt.padding[0]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[0] = "]) + //% self.expect("frame variable pt.padding[1]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[1] = "]) + //% self.expect("expression -- (pt.padding[0])", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["(char)", " = "]) + //% self.expect("image lookup -t point_tag", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['padding[]']) # Once rdar://problem/12566646 is fixed, this should display correctly + + struct rect_tag { + struct point_tag bottom_left; + struct point_tag top_right; + }; + struct point_tag pt = { 2, 3, {} }; + struct rect_tag rect = {{1, 2, {}}, {3, 4, {}}}; + struct things_to_sum tts = { 2, 3, 4 }; + + int sum = sum_things(tts); //% self.expect("expression -- &pt == (struct point_tag*)0", substrs = ['false']) + //% self.expect("expression -- sum_things(tts)", substrs = ['9']) + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/Makefile b/packages/Python/lldbsuite/test/lang/c/tls_globals/Makefile new file mode 100644 index 0000000..90affed --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/Makefile @@ -0,0 +1,11 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS += -fPIC + +DYLIB_NAME := a +DYLIB_C_SOURCES := a.c + +ENABLE_THREADS := YES + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py b/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py new file mode 100644 index 0000000..0d9e22e --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py @@ -0,0 +1,75 @@ +"""Test that thread-local storage can be read correctly.""" + +from __future__ import print_function + + + +import unittest2 +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class TlsGlobalTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + + if self.getPlatform() == "freebsd" or self.getPlatform() == "linux": + # LD_LIBRARY_PATH must be set so the shared libraries are found on startup + if "LD_LIBRARY_PATH" in os.environ: + self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.environ["LD_LIBRARY_PATH"] + ":" + os.getcwd()) + else: + self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd()) + self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath)) + + @unittest2.expectedFailure("rdar://7796742") + @skipIfWindows # TLS works differently on Windows, this would need to be implemented separately. + def test(self): + """Test thread-local storage.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + line1 = line_number('main.c', '// thread breakpoint') + lldbutil.run_break_set_by_file_and_line (self, "main.c", line1, num_expected_locations=1, loc_exact=True) + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.runCmd("process status", "Get process status") + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # BUG: sometimes lldb doesn't change threads to the stopped thread. + # (unrelated to this test). + self.runCmd("thread select 2", "Change thread") + + # Check that TLS evaluates correctly within the thread. + self.expect("expr var_static", VARIABLES_DISPLAYED_CORRECTLY, + patterns = ["\(int\) \$.* = 88"]) + self.expect("expr var_shared", VARIABLES_DISPLAYED_CORRECTLY, + patterns = ["\(int\) \$.* = 66"]) + + # Continue on the main thread + line2 = line_number('main.c', '// main breakpoint') + lldbutil.run_break_set_by_file_and_line (self, "main.c", line2, num_expected_locations=1, loc_exact=True) + self.runCmd("continue", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.runCmd("process status", "Get process status") + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + # BUG: sometimes lldb doesn't change threads to the stopped thread. + # (unrelated to this test). + self.runCmd("thread select 1", "Change thread") + + # Check that TLS evaluates correctly within the main thread. + self.expect("expr var_static", VARIABLES_DISPLAYED_CORRECTLY, + patterns = ["\(int\) \$.* = 44"]) + self.expect("expr var_shared", VARIABLES_DISPLAYED_CORRECTLY, + patterns = ["\(int\) \$.* = 33"]) diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c b/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c new file mode 100644 index 0000000..b9a8590 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c @@ -0,0 +1,18 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <unistd.h> + +__thread int var_shared = 33; + +void shared_check() +{ + var_shared *= 2; + usleep(1); // shared thread breakpoint +} diff --git a/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c b/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c new file mode 100644 index 0000000..cbe01b8 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c @@ -0,0 +1,36 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +void shared_check(); + +// Create some TLS storage within the static executable. +__thread int var_static = 44; + +void *fn_static(void *param) +{ + var_static *= 2; + shared_check(); + usleep(1); // thread breakpoint + for(;;) + usleep(1); +} + +int main (int argc, char const *argv[]) +{ + pthread_t handle; + pthread_create(&handle, NULL, &fn_static, NULL); + + for(;;) + usleep(1); // main breakpoint + + return 0; +} diff --git a/packages/Python/lldbsuite/test/lang/c/typedef/Makefile b/packages/Python/lldbsuite/test/lang/c/typedef/Makefile new file mode 100644 index 0000000..b09a579 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/typedef/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py b/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py new file mode 100644 index 0000000..a4870de --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py @@ -0,0 +1,40 @@ +"""Look up type information for typedefs of same name at different lexical scope and check for correct display.""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + +class TypedefTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(bugnumber="llvm.org/pr19238", compiler="clang") + @expectedFailureAll(bugnumber="llvm.org/pr25626 expectedFailureClang fails on FreeBSD", oslist=["freebsd"]) + def test_typedef(self): + """Test 'image lookup -t a' and check for correct display at different scopes.""" + self.build() + self.image_lookup_for_multiple_typedefs() + + def image_lookup_for_multiple_typedefs(self): + """Test 'image lookup -t a' at different scopes and check for correct display.""" + exe = os.path.join(os.getcwd(), "a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + typearray = ("float", "float", "char", "double *", "float", "int", "double", "float", "float") + arraylen = len(typearray)+1 + for i in range(1,arraylen): + loc_line = line_number('main.c', '// Set break point ' + str(i) + '.') + lldbutil.run_break_set_by_file_and_line (self, "main.c",loc_line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + for t in typearray: + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', 'stop reason = breakpoint']) + self.expect("image lookup -t a", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs = ['name = "' + t + '"']) + self.runCmd("continue") diff --git a/packages/Python/lldbsuite/test/lang/c/typedef/main.c b/packages/Python/lldbsuite/test/lang/c/typedef/main.c new file mode 100644 index 0000000..62f8a00 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/typedef/main.c @@ -0,0 +1,46 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +void test() +{ + typedef double * a; + a b = 0; // Set break point 4. +} +int main (int argc, char const *argv[]) +{ + typedef float a; + int i = 0; // Set break point 1. + i++; + a floatvariable = 2.7; // Set break point 2. + { + typedef char a; + i++; + a charvariable = 'a'; // Set break point 3. + test(); + } + { + int c = 0; + c++; // Set break point 5. + for(i = 0 ; i < 1 ; i++) + { + typedef int a; + a b; + b = 7; // Set break point 6. + } + for(i = 0 ; i < 1 ; i++) + { + typedef double a; + a b; + b = 3.14; // Set break point 7. + } + c = 1; // Set break point 8. + } + floatvariable = 2.5; + floatvariable = 2.8; // Set break point 9. + return 0; +} |