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 000000000000..b09a579159d4 --- /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 000000000000..7cb66ba8238b --- /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 000000000000..58ac85b7d431 --- /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 000000000000..b09a579159d4 --- /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 000000000000..e835fb096496 --- /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 000000000000..8feebe212044 --- /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 000000000000..5f0680a43b84 --- /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 000000000000..b09a579159d4 --- /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 000000000000..de7a333a18fa --- /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 000000000000..26c0176d759c --- /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 000000000000..752b7aed3970 --- /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 000000000000..8f1c3be22836 --- /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 000000000000..415e6c6d033d --- /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 000000000000..51adad1d0622 --- /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 000000000000..a112b2a1777c --- /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 000000000000..c9ea63837c8b --- /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 000000000000..50a924e01d94 --- /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 000000000000..b09a579159d4 --- /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 000000000000..b0c5c882f6a9 --- /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 000000000000..3d59654eff69 --- /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 000000000000..1db43ab479b2 --- /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 000000000000..b7b66f75162b --- /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 000000000000..33c0de2d72d3 --- /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 000000000000..2e050e77778d --- /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 000000000000..3040927cb47a --- /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 000000000000..6f9787c30a36 --- /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 000000000000..b09a579159d4 --- /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 000000000000..2f9f1d10b58c --- /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 000000000000..8be3c4d46b3c --- /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 000000000000..b1b77dacc01e --- /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 000000000000..1f91cd1660c3 --- /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 000000000000..d169d5d63240 --- /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 000000000000..6906a0729aeb --- /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 000000000000..499b2504774f --- /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 000000000000..c5b0d18f995d --- /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 000000000000..1e920f1ef2f6 --- /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 000000000000..265d7b4966ed --- /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 000000000000..b09a579159d4 --- /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 000000000000..cd31f9dbacfe --- /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 000000000000..2b244bc38d02 --- /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 000000000000..b09a579159d4 --- /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 000000000000..1159669ebf15 --- /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 000000000000..12e55616b540 --- /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 000000000000..7ef1f246bfd3 --- /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 000000000000..e467ac48f745 --- /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 000000000000..b09a579159d4 --- /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 000000000000..ab8102496091 --- /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 000000000000..64f01a97a286 --- /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 000000000000..854002e64708 --- /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 000000000000..954d1bac6362 --- /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 000000000000..6431bc496c30 --- /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 000000000000..78b9e3f9c0d9 --- /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 000000000000..b4377de18c16 --- /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 000000000000..51347d73f09c --- /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 000000000000..a9cb46ca137b --- /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 000000000000..6431bc496c30 --- /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 000000000000..78b3c1245387 --- /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 000000000000..b4377de18c16 --- /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 000000000000..b09a579159d4 --- /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 000000000000..c7a3de4b6846 --- /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 000000000000..c3ed3f933ab0 --- /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 000000000000..d8b4a2da761e --- /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 000000000000..b09a579159d4 --- /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 000000000000..6f2a9ff03be0 --- /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 000000000000..e02580b407f5 --- /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 000000000000..cd9ca5c86d84 --- /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 000000000000..87ad326f3181 --- /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 000000000000..29ac10cb94a8 --- /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 000000000000..90affed8e3ad --- /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 000000000000..0d9e22ec3adf --- /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 000000000000..b9a85902d117 --- /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 000000000000..cbe01b89b7ef --- /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 000000000000..b09a579159d4 --- /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 000000000000..a4870de1d177 --- /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 000000000000..62f8a00e6644 --- /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; +}  | 
