1"""Test that anonymous structs/unions are transparent to member access""" 2 3import os, time 4import unittest2 5import lldb 6from lldbtest import * 7import lldbutil 8 9class AnonymousTestCase(TestBase): 10 11 mydir = os.path.join("lang", "c", "anonymous") 12 13 @dsym_test 14 def test_expr_nest_with_dsym(self): 15 self.buildDsym() 16 self.expr_nest() 17 18 @dsym_test 19 def test_expr_child_with_dsym(self): 20 self.buildDsym() 21 self.expr_child() 22 23 @dsym_test 24 def test_expr_grandchild_with_dsym(self): 25 self.buildDsym() 26 self.expr_grandchild() 27 28 @dsym_test 29 def test_expr_parent(self): 30 self.buildDsym() 31 self.expr_parent() 32 33 @unittest2.expectedFailure # llvm.org/pr15591 34 @dsym_test 35 def test_expr_null(self): 36 self.buildDsym() 37 self.expr_null() 38 39 @skipIfGcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by GCC 40 @skipIfIcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC 41 @dwarf_test 42 def test_expr_nest_with_dwarf(self): 43 self.buildDwarf() 44 self.expr_nest() 45 46 @dwarf_test 47 def test_expr_child_with_dwarf(self): 48 self.skipTest("Skipped because LLDB asserts due to an incorrect AST layout for an anonymous struct: see llvm.org/pr15036") 49 self.buildDwarf() 50 self.expr_child() 51 52 @skipIfGcc # llvm.org/pr15036: This particular regression was introduced by r181498 53 @skipIfIcc # llvm.org/pr15036: This particular regression was introduced by r181498 54 @dwarf_test 55 def test_expr_grandchild_with_dwarf(self): 56 self.buildDwarf() 57 self.expr_grandchild() 58 59 @dwarf_test 60 def test_expr_parent(self): 61 self.buildDwarf() 62 self.expr_parent() 63 64 @unittest2.expectedFailure # llvm.org/pr15591 65 @dwarf_test 66 def test_expr_null(self): 67 self.buildDwarf() 68 self.expr_null() 69 70 def setUp(self): 71 # Call super's setUp(). 72 TestBase.setUp(self) 73 # Find the line numbers to break in main.c. 74 self.line0 = line_number('main.c', '// Set breakpoint 0 here.') 75 self.line1 = line_number('main.c', '// Set breakpoint 1 here.') 76 self.line2 = line_number('main.c', '// Set breakpoint 2 here.') 77 78 def common_setup(self, line): 79 exe = os.path.join(os.getcwd(), "a.out") 80 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 81 82 # Set breakpoints inside and outside methods that take pointers to the containing struct. 83 lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True) 84 85 self.runCmd("run", RUN_SUCCEEDED) 86 87 # The stop reason of the thread should be breakpoint. 88 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 89 substrs = ['stopped', 90 'stop reason = breakpoint']) 91 92 # The breakpoint should have a hit count of 1. 93 self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, 94 substrs = [' resolved, hit count = 1']) 95 96 def expr_nest(self): 97 self.common_setup(self.line0) 98 99 # These should display correctly. 100 self.expect("expression n->foo.d", VARIABLES_DISPLAYED_CORRECTLY, 101 substrs = ["= 4"]) 102 103 self.expect("expression n->b", VARIABLES_DISPLAYED_CORRECTLY, 104 substrs = ["= 2"]) 105 106 def expr_child(self): 107 self.common_setup(self.line1) 108 109 # These should display correctly. 110 self.expect("expression c->foo.d", VARIABLES_DISPLAYED_CORRECTLY, 111 substrs = ["= 4"]) 112 113 self.expect("expression c->grandchild.b", VARIABLES_DISPLAYED_CORRECTLY, 114 substrs = ["= 2"]) 115 116 def expr_grandchild(self): 117 self.common_setup(self.line2) 118 119 # These should display correctly. 120 self.expect("expression g.child.foo.d", VARIABLES_DISPLAYED_CORRECTLY, 121 substrs = ["= 4"]) 122 123 self.expect("expression g.child.b", VARIABLES_DISPLAYED_CORRECTLY, 124 substrs = ["= 2"]) 125 126 def expr_parent(self): 127 if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): 128 self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") 129 self.common_setup(self.line2) 130 131 # These should display correctly. 132 self.expect("expression pz", VARIABLES_DISPLAYED_CORRECTLY, 133 substrs = ["(type_z *) $0 = 0x0000"]) 134 135 self.expect("expression z.y", VARIABLES_DISPLAYED_CORRECTLY, 136 substrs = ["(type_y) $1 = {"]) 137 138 self.expect("expression z", VARIABLES_DISPLAYED_CORRECTLY, 139 substrs = ["dummy = 2"]) 140 141 def expr_null(self): 142 self.common_setup(self.line2) 143 144 # This should fail because pz is 0, but it succeeds on OS/X. 145 # This fails on Linux with an upstream error "Couldn't dematerialize struct", as does "p *n" with "int *n = 0". 146 # Note that this can also trigger llvm.org/pr15036 when run interactively at the lldb command prompt. 147 self.expect("expression *(type_z *)pz", 148 substrs = ["Cannot access memory at address 0x0"], error = True) 149 150 151if __name__ == '__main__': 152 import atexit 153 lldb.SBDebugger.Initialize() 154 atexit.register(lambda: lldb.SBDebugger.Terminate()) 155 unittest2.main() 156