1""" 2Test lldb data formatter subsystem. 3""" 4 5import os, time 6import unittest2 7import lldb 8from lldbtest import * 9import lldbutil 10 11class ScriptDataFormatterTestCase(TestBase): 12 13 mydir = os.path.join("functionalities", "data-formatter", "data-formatter-script") 14 15 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") 16 @dsym_test 17 def test_with_dsym_and_run_command(self): 18 """Test data formatter commands.""" 19 self.buildDsym() 20 self.data_formatter_commands() 21 22 @dwarf_test 23 def test_with_dwarf_and_run_command(self): 24 """Test data formatter commands.""" 25 self.buildDwarf() 26 self.data_formatter_commands() 27 28 def setUp(self): 29 # Call super's setUp(). 30 TestBase.setUp(self) 31 # Find the line number to break at. 32 self.line = line_number('main.cpp', '// Set break point at this line.') 33 34 def data_formatter_commands(self): 35 """Test that that file and class static variables display correctly.""" 36 self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) 37 38 lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 39 40 self.runCmd("run", RUN_SUCCEEDED) 41 42 # The stop reason of the thread should be breakpoint. 43 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 44 substrs = ['stopped', 45 'stop reason = breakpoint']) 46 47 # This is the function to remove the custom formats in order to have a 48 # clean slate for the next test case. 49 def cleanup(): 50 self.runCmd('type format clear', check=False) 51 self.runCmd('type summary clear', check=False) 52 53 # Execute the cleanup function during test case tear down. 54 self.addTearDownHook(cleanup) 55 56 # Set the script here to ease the formatting 57 script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');' 58 59 self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script) 60 61 self.expect("frame variable one", 62 substrs = ['Hello from Python', 63 '1 time!']) 64 65 self.expect("frame variable two", 66 substrs = ['Hello from Python', 67 '4 times!']) 68 69 self.runCmd("n"); # skip ahead to make values change 70 71 self.expect("frame variable three", 72 substrs = ['Hello from Python, 10 times!', 73 'Hello from Python, 4 times!']) 74 75 self.runCmd("n"); # skip ahead to make values change 76 77 self.expect("frame variable two", 78 substrs = ['Hello from Python', 79 '1 time!']) 80 81 script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'int says \' + a_val; return str;' 82 83 # Check that changes in the script are immediately reflected 84 self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script) 85 86 self.expect("frame variable two", 87 substrs = ['int says 1']) 88 89 self.expect("frame variable twoptr", 90 substrs = ['int says 1']) 91 92 # Change the summary 93 self.runCmd("type summary add --summary-string \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool") 94 95 self.expect("frame variable two", 96 substrs = ['int says 1', 97 'and float says 2.71']) 98 # Try it for pointers 99 self.expect("frame variable twoptr", 100 substrs = ['int says 1', 101 'and float says 2.71']) 102 103 # Force a failure for pointers 104 self.runCmd("type summary add i_am_cool -p --python-script \"%s\"" % script) 105 106 self.expect("frame variable twoptr", matching=False, 107 substrs = ['and float says 2.71']) 108 109 script = 'return \'Python summary\''; 110 111 self.runCmd("type summary add --name test_summary --python-script \"%s\"" % script) 112 113 # attach the Python named summary to someone 114 self.expect("frame variable one --summary test_summary", 115 substrs = ['Python summary']) 116 117 # should not bind to the type 118 self.expect("frame variable two", matching=False, 119 substrs = ['Python summary']) 120 121 # and should not stick to the variable 122 self.expect("frame variable one",matching=False, 123 substrs = ['Python summary']) 124 125 self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"") 126 127 # should be temporary only 128 self.expect("frame variable one",matching=False, 129 substrs = ['Python summary']) 130 131 # use the type summary 132 self.expect("frame variable two", 133 substrs = ['Text summary']) 134 135 self.runCmd("n"); # skip ahead to make values change 136 137 # both should use the type summary now 138 self.expect("frame variable one", 139 substrs = ['Text summary']) 140 141 self.expect("frame variable two", 142 substrs = ['Text summary']) 143 144 # disable type summary for pointers, and make a Python regex summary 145 self.runCmd("type summary add i_am_cool -p --summary-string \"Text summary\"") 146 self.runCmd("type summary add -x cool --python-script \"%s\"" % script) 147 148 # variables should stick to the type summary 149 self.expect("frame variable one", 150 substrs = ['Text summary']) 151 152 self.expect("frame variable two", 153 substrs = ['Text summary']) 154 155 # array and pointer should match the Python one 156 self.expect("frame variable twoptr", 157 substrs = ['Python summary']) 158 159 self.expect("frame variable array", 160 substrs = ['Python summary']) 161 162 # return pointers to the type summary 163 self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"") 164 165 self.expect("frame variable one", 166 substrs = ['Text summary']) 167 168 self.expect("frame variable two", 169 substrs = ['Text summary']) 170 171 self.expect("frame variable twoptr", 172 substrs = ['Text summary']) 173 174 self.expect("frame variable array", 175 substrs = ['Python summary']) 176 177 178if __name__ == '__main__': 179 import atexit 180 lldb.SBDebugger.Initialize() 181 atexit.register(lambda: lldb.SBDebugger.Terminate()) 182 unittest2.main() 183