def test(self): """Break inside a() and b() defined within libfoo.a.""" self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside a() by file and line first. lldbutil.run_break_set_by_file_and_line(self, "a.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"]) # Break at a(int) first. self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, substrs=["(int) arg = 1"]) self.expect("frame variable __a_global", VARIABLES_DISPLAYED_CORRECTLY, substrs=["(int) __a_global = 1"]) # Set breakpoint for b() next. lldbutil.run_break_set_by_symbol(self, "b", num_expected_locations=1, sym_exact=True) # Continue the program, we should break at b(int) next. self.runCmd("continue") self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=["stopped", "stop reason = breakpoint"]) self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY, substrs=["(int) arg = 2"]) self.expect("frame variable __b_global", VARIABLES_DISPLAYED_CORRECTLY, substrs=["(int) __b_global = 2"])
def inferior_not_crashing(self): """Test lldb reloads the inferior after it was changed during the session.""" self.runCmd("process kill") self.runCmd("run", RUN_SUCCEEDED) self.runCmd("process status") self.assertNotEqual( len(lldbutil.get_crashed_threads(self, self.dbg.GetSelectedTarget().GetProcess())), 1, "Inferior changed, but lldb did not perform a reload") # Break inside the main. lldbutil.run_break_set_by_file_and_line (self, "main2.c", self.line2, 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']) self.runCmd("frame variable int_ptr") self.expect("frame variable *int_ptr", substrs = ['= 7']) self.expect("expression *int_ptr", substrs = ['= 7'])
def data_formatter_commands(self): """Test printing out Python summary formatters.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type category delete TSLSFormatters', check=False) self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.addTearDownHook(cleanup) self.runCmd("command script import tslsformatters.py") self.expect("frame variable myStruct", substrs=['A data formatter at work']) self.expect('type summary list', substrs=['Struct_SummaryFormatter']) self.expect('type summary list Struct', substrs=['Struct_SummaryFormatter'])
def test(self): """Test that variables with unsigned types display correctly.""" self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # GCC puts a breakpoint on the last line of a multi-line expression, so # if GCC is the target compiler, we cannot rely on an exact line match. need_exact = "gcc" not in self.getCompiler() # Break on line 19 in main() aftre the variables are assigned values. lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=need_exact) 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']) # Test that unsigned types display correctly. self.expect("frame variable --show-types --no-args", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(unsigned char) the_unsigned_char = 'c'", patterns = ["\((short unsigned int|unsigned short)\) the_unsigned_short = 99"], substrs = ["(unsigned int) the_unsigned_int = 99", "(unsigned long) the_unsigned_long = 99", "(unsigned long long) the_unsigned_long_long = 99", "(uint32_t) the_uint32 = 99"])
def test_with_run_command(self): """Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): pass # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # extract the parent and the children frame = self.frame() parent = self.frame().FindVariable("f") self.assertTrue( parent is not None and parent.IsValid(), "could not find f") X = parent.GetChildMemberWithName("X") self.assertTrue(X is not None and X.IsValid(), "could not find X") Y = parent.GetChildMemberWithName("Y") self.assertTrue(Y is not None and Y.IsValid(), "could not find Y") # check their values now self.assertTrue(X.GetValue() == "1", "X has an invalid value") self.assertTrue(Y.GetValue() == "2", "Y has an invalid value") # set the format on the parent parent.SetFormat(lldb.eFormatHex) self.assertTrue( X.GetValue() == "0x00000001", "X has not changed format") self.assertTrue( Y.GetValue() == "0x00000002", "Y has not changed format") # Step and check if the values make sense still self.runCmd("next") self.assertTrue(X.GetValue() == "0x00000004", "X has not become 4") self.assertTrue(Y.GetValue() == "0x00000002", "Y has not stuck as hex") # Check that children can still make their own choices Y.SetFormat(lldb.eFormatDecimal) self.assertTrue(X.GetValue() == "0x00000004", "X is still hex") self.assertTrue(Y.GetValue() == "2", "Y has not been reset") # Make a few more changes parent.SetFormat(lldb.eFormatDefault) X.SetFormat(lldb.eFormatHex) Y.SetFormat(lldb.eFormatDefault) self.assertTrue( X.GetValue() == "0x00000004", "X is not hex as it asked") self.assertTrue(Y.GetValue() == "2", "Y is not defaulted")
def thread_state_after_expression_test(self): """Test thread state after expression.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint in the main thread. lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Get the inferior out of its loop self.runCmd("expression g_test = 1") # Check the thread state self.assertTrue(thread.IsStopped(), "Thread state isn't \'stopped\' after expression evaluation.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' after expression evaluation.") # Let the process run to completion self.runCmd("process continue")
def thread_state_after_continue_test(self): """Test thread state after continue.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint in the main thread. lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_1, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.break_2, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) # Continue, the inferior will go into an infinite loop waiting for 'g_test' to change. self.dbg.SetAsync(True) self.runCmd("continue") self.wait_for_running_event(process) # Check the thread state. It should be running. self.assertFalse(thread.IsStopped(), "Thread state is \'stopped\' when it should be running.") self.assertFalse(thread.IsSuspended(), "Thread state is \'suspended\' when it should be running.") # Go back to synchronous interactions self.dbg.SetAsync(False) # Kill the process self.runCmd("process kill")
def test_expr(self): 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.m", 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.runCmd("settings set target.clang-module-search-paths \"" + os.getcwd() + "\"") self.expect("expr @import myModule; 3", VARIABLES_DISPLAYED_CORRECTLY, substrs = ["int", "3"]) self.expect("expr [myObject privateMethod]", VARIABLES_DISPLAYED_CORRECTLY, substrs = ["int", "5"]) self.expect("expr MIN(2,3)", "#defined macro was found", substrs = ["int", "2"]) self.expect("expr MAX(2,3)", "#undefd macro was correcltly not found", error=True)
def test_with_run_command(self): """Test that LLDB correctly cleans caches when language categories change.""" # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): if hasattr(self, 'type_category') and hasattr(self, 'type_specifier'): self.type_category.DeleteTypeSummary(self.type_specifier) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", 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']) self.expect("frame variable", substrs = ['(S)', 'object', '123', '456'], matching=True) self.type_category = self.dbg.GetCategory(lldb.eLanguageTypeC_plus_plus) type_summary = lldb.SBTypeSummary.CreateWithSummaryString("this is an object of type S") self.type_specifier = lldb.SBTypeNameSpecifier('S') self.type_category.AddTypeSummary(self.type_specifier, type_summary) self.expect("frame variable", substrs = ['this is an object of type S'], matching=True) self.type_category.DeleteTypeSummary(self.type_specifier) self.expect("frame variable", substrs = ['this is an object of type S'], matching=False) self.expect("frame variable", substrs = ['(S)', 'object', '123', '456'], matching=True)
def sanity_check_executable(self, exe_name): """Sanity check executable compiled from the auto-generated program.""" exe = os.path.join(os.getcwd(), exe_name) self.runCmd("file %s" % exe, CURRENT_EXECUTABLE_SET) self.line_to_break = line_number( self.source, '// Set breakpoint here.') env_cmd = "settings set target.env-vars %s=%s" % ( self.dylibPath, self.getLLDBLibraryEnvVal()) if self.TraceOn(): print("Set environment to: ", env_cmd) self.runCmd(env_cmd) self.addTearDownHook( lambda: self.dbg.HandleCommand( "settings remove target.env-vars %s" % self.dylibPath)) lldbutil.run_break_set_by_file_and_line( self, self.source, self.line_to_break, 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']) self.runCmd('frame variable')
def common_setup(self, preload_symbols = True): # 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) self.runCmd("settings set target.preload-symbols " + str(preload_symbols).lower()) # 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'])
def test_step_over_load (self): """Test stepping over code that loads a shared library works correctly.""" # Invoke the default build rule. self.build() self.copy_shlibs_to_remote() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break by function name a_function (not yet loaded). 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 and at a_function. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) self.runCmd("thread step-over", "Stepping over function that loads library") # The stop reason should be step end. self.expect("thread list", "step over succeeded.", substrs = ['stopped', 'stop reason = step over'])
def test(self): """Test breakpoint handling after a thread join.""" self.build(dictionary=self.getBuildFlags()) exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint lldbutil.run_break_set_by_file_and_line (self, "ParallelTask.cpp", self.breakpoint, num_expected_locations=-1) # The breakpoint list should show 1 location. self.expect("breakpoint list -f", "Breakpoint location shown correctly", substrs = ["1: file = 'ParallelTask.cpp', line = %d, exact_match = 0" % self.breakpoint]) # Run the program. 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']) # This should not result in a segmentation fault self.expect("thread backtrace all", STOPPED_DUE_TO_BREAKPOINT, substrs = ["stop reason = breakpoint 1."]) # Run to completion self.runCmd("continue")
def test_type_lookup(self): """Test type lookup command.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.mm", 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']) self.expect( 'type lookup NoSuchType', substrs=['@interface'], matching=False) self.expect('type lookup NSURL', substrs=['NSURL']) self.expect('type lookup NSArray', substrs=['NSArray']) self.expect('type lookup NSObject', substrs=['NSObject', 'isa']) self.expect('type lookup PleaseDontBeARealTypeThatExists', substrs=[ "no type was found matching 'PleaseDontBeARealTypeThatExists'"]) self.expect('type lookup MyCPPClass', substrs=['setF', 'float getF']) self.expect('type lookup MyClass', substrs=['setF', 'float getF']) self.expect('type lookup MyObjCClass', substrs=['@interface MyObjCClass', 'int x', 'int y'])
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+")) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect("frame variable vBool", substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true']) self.expect("expr vBool", substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
def test_with_run_command(self): """Test using Python synthetic children provider.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.runCmd("command script import helperfunc.py") self.runCmd('type summary add -x "^something<.*>$" -s "T is a ${script.var:helperfunc.f}"') self.expect("frame variable x", substrs = ['T is a non-pointer type']); self.expect("frame variable y", substrs = ['T is a pointer type']);
def test_more_expr_commands(self): """Test some more expression commands.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False) self.runCmd("run", RUN_SUCCEEDED) # Does static casting work? self.expect("expression (int*)argv", startstr="(int *) $0 = 0x") # (int *) $0 = 0x00007fff5fbff258 # Do return values containing the contents of expression locals work? self.expect("expression int i = 5; i", startstr="(int) $1 = 5") # (int) $2 = 5 self.expect("expression $1 + 1", startstr="(int) $2 = 6") # (int) $3 = 6 # Do return values containing the results of static expressions work? self.expect("expression 20 + 3", startstr="(int) $3 = 23") # (int) $4 = 5 self.expect("expression $3 + 1", startstr="(int) $4 = 24")
def test_ostype_with_run_command(self): """Test the formatters we use for OSType.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.mm", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type synth clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # Now check that we use the right summary for OSType self.expect('frame variable', substrs=["'test'", "'best'"])
def test(self): """Test that variables with signed types display correctly.""" self.build() # 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) lldbutil.run_break_set_by_file_and_line (self, self.source, self.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']) # Execute the assignment statement. self.runCmd("thread step-over") # Test that signed types display correctly. self.expect("frame variable --show-types --no-args", VARIABLES_DISPLAYED_CORRECTLY, patterns = ["\((short int|short)\) the_signed_short = 99", "\((signed char|char)\) the_signed_char = 'c'"], substrs = ["(int) the_signed_int = 99", "(long) the_signed_long = 99", "(long long) the_signed_long_long = 99"])
def test_phi_node_support(self): """Test support for PHI nodes in the IR interpreter.""" self.build() exe = os.path.join(os.getcwd(), 'a.out') self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET) # Break on the first assignment to i line = line_number('main.cpp', 'i = 5') lldbutil.run_break_set_by_file_and_line( self, 'main.cpp', 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']) self.runCmd('s') # The logical 'or' causes a PHI node to be generated. Execute without JIT # to test that the interpreter can handle this self.expect('expr -j 0 -- i == 3 || i == 5', substrs=['true']) self.runCmd('s') self.expect('expr -j 0 -- i == 3 || i == 5', substrs=['false']) self.runCmd('s') self.expect('expr -j 0 -- i == 3 || i == 5', substrs=['true'])
def test_with_run_command(self): """Test 'frame variable this' when stopped on a class constructor.""" self.build() exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break on the ctor function of class C. lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line, num_expected_locations=-1) self.runCmd("run", RUN_SUCCEEDED) # The test suite sometimes shows that the process has exited without stopping. # # CC=clang ./dotest.py -v -t class_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']) # We should be stopped on the ctor function of class C. self.expect( "frame variable --show-types this", VARIABLES_DISPLAYED_CORRECTLY, substrs=[ 'C *', ' this = '])
def test_watchpoint_command(self): """Test 'watchpoint command'.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) exe = os.path.join(os.getcwd(), self.exe_name) self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line( self, None, self.line, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # Now let's set a write-type watchpoint for 'global'. self.expect( "watchpoint set variable -w write global", WATCHPOINT_CREATED, substrs=[ 'Watchpoint created', 'size = 4', 'type = w', '%s:%d' % (self.source, self.decl)]) self.runCmd('watchpoint command add 1 -o "expr -- cookie = 777"') # List the watchpoint command we just added. self.expect("watchpoint command list 1", substrs=['expr -- cookie = 777']) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should be 0 initially. self.expect("watchpoint list -v", substrs=['hit_count = 0']) self.runCmd("process continue") # We should be stopped again due to the watchpoint (write type). # The stop reason of the thread should be watchpoint. self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT, substrs=['stop reason = watchpoint']) # Check that the watchpoint snapshoting mechanism is working. self.expect("watchpoint list -v", substrs=['old value:', ' = 0', 'new value:', ' = 1']) # The watchpoint command "forced" our global variable 'cookie' to # become 777. self.expect("frame variable --show-globals cookie", substrs=['(int32_t)', 'cookie = 777'])
def test_NSArray_expr_commands(self): """Test expression commands for NSArray.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside Test_NSArray: line = self.lines[1] lldbutil.run_break_set_by_file_and_line( self, "main.m", line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # Test_NSArray: self.runCmd("thread backtrace") self.expect("expression (int)[nil_mutable_array count]", patterns=["\(int\) \$.* = 0"]) self.expect("expression (int)[array1 count]", patterns=["\(int\) \$.* = 3"]) self.expect("expression (int)[array2 count]", patterns=["\(int\) \$.* = 3"]) self.expect("expression (int)array1.count", patterns=["\(int\) \$.* = 3"]) self.expect("expression (int)array2.count", patterns=["\(int\) \$.* = 3"]) self.runCmd("process continue")
def rdar12991846(self, expr=None): """Test that the expression parser returns proper Unicode strings.""" if self.getArchitecture() in ['i386']: self.skipTest("Skipping because this test is known to crash on i386") exe = os.path.join(os.getcwd(), "a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Break on the struct declration statement in main.cpp. lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line) # Now launch the process, and do not stop at entry point. process = target.LaunchSimple (None, None, self.get_process_working_directory()) if not process: self.fail("SBTarget.Launch() failed") if expr == 1: self.expect('expression L"hello"', substrs = ['hello']) if expr == 2: self.expect('expression u"hello"', substrs = ['hello']) if expr == 3: self.expect('expression U"hello"', substrs = ['hello'])
def test_NSString_expr_commands(self): """Test expression commands for NSString.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break inside Test_NSString: line = self.lines[2] lldbutil.run_break_set_by_file_and_line( self, "main.m", line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) # Test_NSString: self.runCmd("thread backtrace") self.expect("expression (int)[str length]", patterns=["\(int\) \$.* ="]) self.expect("expression (int)[str_id length]", patterns=["\(int\) \$.* ="]) self.expect("expression (id)[str description]", patterns=["\(id\) \$.* = 0x"]) self.expect("expression (id)[str_id description]", patterns=["\(id\) \$.* = 0x"]) self.expect("expression str.length") self.expect('expression str = @"new"') self.runCmd("image lookup -t NSString") self.expect('expression str = (id)[NSString stringWithCString: "new"]') self.runCmd("process continue")
def test(self): """Test thread jump handling.""" self.build(dictionary=self.getBuildFlags()) exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Find the line numbers for our breakpoints. self.mark1 = line_number('main.cpp', '// 1st marker') self.mark2 = line_number('main.cpp', '// 2nd marker') self.mark3 = line_number('main.cpp', '// 3rd marker') self.mark4 = line_number('main.cpp', '// 4th marker') self.mark5 = line_number('other.cpp', '// other marker') lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.mark3, num_expected_locations=1) self.runCmd("run", RUN_SUCCEEDED) # The stop reason of the thread should be breakpoint 1. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT + " 1", substrs = ['stopped', '* thread #1', 'stop reason = breakpoint 1']) self.do_min_test(self.mark3, self.mark1, "i", "4"); # Try the int path, force it to return 'a' self.do_min_test(self.mark3, self.mark2, "i", "5"); # Try the int path, force it to return 'b' self.do_min_test(self.mark4, self.mark1, "j", "7"); # Try the double path, force it to return 'a' self.do_min_test(self.mark4, self.mark2, "j", "8"); # Try the double path, force it to return 'b' # Try jumping to another function in a different file. self.runCmd("thread jump --file other.cpp --line %i --force" % self.mark5) self.expect("process status", substrs = ["at other.cpp:%i" % self.mark5]) # Try jumping to another function (without forcing) self.expect("j main.cpp:%i" % self.mark1, COMMAND_FAILED_AS_EXPECTED, error = True, substrs = ["error"])
def test_with_run_command(self): """Verify that the hash computing logic for ValueObject's values can't crash us.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", 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']) value = self.frame().FindVariable("a") value.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) v = value.GetValue() type_name = value.GetTypeName() self.assertTrue(type_name == "B *", "a is a B*") self.runCmd("next") self.runCmd("process kill") # now the process is dead, and value needs updating v = value.GetValue()
def mpx_registers_with_example_code(self): """Test MPX registers after running example code.""" self.line = line_number('main.cpp', '// Set a break point here.') 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.cpp", self.line, num_expected_locations=1) self.runCmd("run", RUN_SUCCEEDED) target = self.dbg.GetSelectedTarget() process = target.GetProcess() if (process.GetState() == lldb.eStateExited): self.skipTest("HW doesn't support MPX feature.") else: self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, substrs = ["stop reason = breakpoint 1."]) if self.getArchitecture() == 'x86_64': self.expect("register read -s 3", substrs = ['bnd0 = {0x0000000000000010 0xffffffffffffffe6}', 'bnd1 = {0x0000000000000020 0xffffffffffffffd6}', 'bnd2 = {0x0000000000000030 0xffffffffffffffc6}', 'bnd3 = {0x0000000000000040 0xffffffffffffffb6}', 'bndcfgu = {0x01 0x80 0xb5 0x76 0xff 0x7f 0x00 0x00}', 'bndstatus = {0x02 0x80 0xb5 0x76 0xff 0x7f 0x00 0x00}']) if self.getArchitecture() == 'i386': self.expect("register read -s 3", substrs = ['bnd0 = {0x0000000000000010 0x00000000ffffffe6}', 'bnd1 = {0x0000000000000020 0x00000000ffffffd6}', 'bnd2 = {0x0000000000000030 0x00000000ffffffc6}', 'bnd3 = {0x0000000000000040 0x00000000ffffffb6}', 'bndcfgu = {0x01 0xd0 0x7d 0xf7 0x00 0x00 0x00 0x00}', 'bndstatus = {0x02 0xd0 0x7d 0xf7 0x00 0x00 0x00 0x00}'])
def test_with_run_command(self): """Test that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", 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']) # global variables are no longer displayed with the "frame variable" command. self.expect('target variable A::g_points', VARIABLES_DISPLAYED_CORRECTLY, patterns=['\(PointType \[[1-9]*\]\) A::g_points = {.*}']) self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY, substrs = ['(PointType [2]) g_points']) # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. # A::g_points is an array of two elements. if self.platformIsDarwin() or self.getPlatform() == "linux": self.expect("target variable A::g_points[1].x", VARIABLES_DISPLAYED_CORRECTLY, startstr = "(int) A::g_points[1].x = 11")
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1) self.runCmd("run", RUN_SUCCEEDED) lldbutil.skip_if_library_missing(self, self.target(), lldbutil.PrintableRegex("libc\+\+")) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs = ['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd("settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.expect("frame variable", substrs = ['(std::__1::wstring) s = L"hello world! מזל טוב!"', '(std::__1::wstring) S = L"!!!!"', '(const wchar_t *) mazeltov = 0x','L"מזל טוב"', '(std::__1::string) q = "hello world"', '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"', '(std::__1::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"', '(std::__1::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"']) self.runCmd("n") TheVeryLongOne = self.frame().FindVariable("TheVeryLongOne"); summaryOptions = lldb.SBTypeSummaryOptions() summaryOptions.SetCapping(lldb.eTypeSummaryUncapped) uncappedSummaryStream = lldb.SBStream() TheVeryLongOne.GetSummary(uncappedSummaryStream,summaryOptions) uncappedSummary = uncappedSummaryStream.GetData() self.assertTrue(uncappedSummary.find("someText") > 0, "uncappedSummary does not include the full string") summaryOptions.SetCapping(lldb.eTypeSummaryCapped) cappedSummaryStream = lldb.SBStream() TheVeryLongOne.GetSummary(cappedSummaryStream,summaryOptions) cappedSummary = cappedSummaryStream.GetData() self.assertTrue(cappedSummary.find("someText") <= 0, "cappedSummary includes the full string") self.expect("frame variable", substrs = ['(std::__1::wstring) s = L"hello world! מזל טוב!"', '(std::__1::wstring) S = L"!!!!!"', '(const wchar_t *) mazeltov = 0x','L"מזל טוב"', '(std::__1::string) q = "hello world"', '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"', '(std::__1::string) IHaveEmbeddedZeros = "a\\0b\\0c\\0d"', '(std::__1::wstring) IHaveEmbeddedZerosToo = L"hello world!\\0てざ ル゜䋨ミ㠧槊 きゅへ狦穤襩 じゃ馩リョ 䤦監"'])
def create_after_attach(self, use_fork): """Test thread creation after process attach.""" exe = os.path.join(os.getcwd(), "a.out") # Spawn a new process if use_fork: pid = self.forkSubprocess(exe) else: popen = self.spawnSubprocess(exe) pid = popen.pid self.addTearDownHook(self.cleanupSubprocesses) # Attach to the spawned process self.runCmd("process attach -p " + str(pid)) target = self.dbg.GetSelectedTarget() process = target.GetProcess() self.assertTrue(process, PROCESS_IS_VALID) # This should create a breakpoint in the main thread. lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_1, num_expected_locations=1) # This should create a breakpoint in the second child thread. lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_2, num_expected_locations=1) # This should create a breakpoint in the first child thread. lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_3, num_expected_locations=1) # Note: With std::thread, we cannot rely on particular thread numbers. Using # std::thread may cause the program to spin up a thread pool (and it does on # Windows), so the thread numbers are non-deterministic. # Run to the first breakpoint self.runCmd("continue") # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', '* thread #', 'main', 'stop reason = breakpoint']) # Change a variable to escape the loop self.runCmd("expression main_thread_continue = 1") # Run to the second breakpoint self.runCmd("continue") # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', '* thread #', 'thread_2_func', 'stop reason = breakpoint']) # Change a variable to escape the loop self.runCmd("expression child_thread_continue = 1") # Run to the third breakpoint self.runCmd("continue") # The stop reason of the thread should be breakpoint. # Thread 3 may or may not have already exited. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', '* thread #', 'thread_1_func', 'stop reason = breakpoint']) # Run to completion self.runCmd("continue") # At this point, the inferior process should have exited. self.assertTrue( process.GetState() == lldb.eStateExited, PROCESS_EXITED)
def test_dyn(self): """Test that we are able to properly report a usable dynamic type.""" d = {'EXE': self.exe_name} self.build(dictionary=d) self.setTearDownCleanup(dictionary=d) exe = os.path.join(os.getcwd(), self.exe_name) self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, self.main_source, self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) v_object = self.frame().FindVariable("object").GetDynamicValue( lldb.eDynamicCanRunTarget) v_base = self.frame().FindVariable("base").GetDynamicValue( lldb.eDynamicCanRunTarget) self.assertTrue(v_object.GetTypeName() == "MyDerivedClass *", "The NSObject is properly type-named") self.assertTrue(v_base.GetTypeName() == "MyDerivedClass *", "The Base is properly type-named") object_type = v_object.GetType() base_type = v_base.GetType() self.assertTrue( object_type.GetName() == "MyDerivedClass *", "The dynamic SBType for NSObject is for the correct type") self.assertTrue(base_type.GetName() == "MyDerivedClass *", "The dynamic SBType for Base is for the correct type") object_pointee_type = object_type.GetPointeeType() base_pointee_type = base_type.GetPointeeType() self.assertTrue( object_pointee_type.GetName() == "MyDerivedClass", "The dynamic type for NSObject figures out its pointee type just fine" ) self.assertTrue( base_pointee_type.GetName() == "MyDerivedClass", "The dynamic type for Base figures out its pointee type just fine") self.assertTrue( object_pointee_type.GetDirectBaseClassAtIndex( 0).GetName() == "MyBaseClass", "The dynamic type for NSObject can go back to its base class") self.assertTrue( base_pointee_type.GetDirectBaseClassAtIndex( 0).GetName() == "MyBaseClass", "The dynamic type for Base can go back to its base class") self.assertTrue( object_pointee_type.GetDirectBaseClassAtIndex(0).GetType( ).GetDirectBaseClassAtIndex(0).GetName() == "NSObject", "The dynamic type for NSObject can go up the hierarchy") self.assertTrue( base_pointee_type.GetDirectBaseClassAtIndex(0).GetType( ).GetDirectBaseClassAtIndex(0).GetName() == "NSObject", "The dynamic type for Base can go up the hierarchy") self.assertTrue(object_pointee_type.GetNumberOfFields() == 2, "The dynamic type for NSObject has 2 fields") self.assertTrue(base_pointee_type.GetNumberOfFields() == 2, "The dynamic type for Base has 2 fields")
def breakpoint_command_sequence(self): """Test a sequence of breakpoint command add, list, and delete.""" exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add three breakpoints on the same line. The first time we don't specify the file, # since the default file is the one containing main: lldbutil.run_break_set_by_file_and_line(self, None, self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "main.c", self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "main.c", self.line, num_expected_locations=1, loc_exact=True) # Breakpoint 4 - set at the same location as breakpoint 1 to test # setting breakpoint commands on two breakpoints at a time lldbutil.run_break_set_by_file_and_line(self, None, self.line, num_expected_locations=1, loc_exact=True) # Make sure relative path source breakpoints work as expected. We test # with partial paths with and without "./" prefixes. lldbutil.run_break_set_by_file_and_line(self, "./main.c", self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "breakpoint_command/main.c", self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "./breakpoint_command/main.c", self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line( self, "breakpoint/breakpoint_command/main.c", self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line( self, "./breakpoint/breakpoint_command/main.c", self.line, num_expected_locations=1, loc_exact=True) # Test relative breakpoints with incorrect paths and make sure we get # no breakpoint locations lldbutil.run_break_set_by_file_and_line(self, "invalid/main.c", self.line, num_expected_locations=0, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "./invalid/main.c", self.line, num_expected_locations=0, loc_exact=True) # Now add callbacks for the breakpoints just created. self.runCmd( "breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4" ) self.runCmd( "breakpoint command add -s python -o 'import side_effect; side_effect.one_liner = \"one liner was here\"' 2" ) import side_effect self.runCmd("command script import --allow-reload ./bktptcmd.py") self.runCmd( "breakpoint command add --python-function bktptcmd.function 3") # Check that the breakpoint commands are correctly set. # The breakpoint list now only contains breakpoint 1. self.expect( "breakpoint list", "Breakpoints 1 & 2 created", substrs=[ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line ], patterns=[ "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line ]) self.expect( "breakpoint list -f", "Breakpoints 1 & 2 created", substrs=[ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line ], patterns=[ "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line, "1.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" % self.line, "2.1: .+at main.c:%d:?[0-9]*, .+unresolved, hit count = 0" % self.line ]) self.expect("breakpoint command list 1", "Breakpoint 1 command ok", substrs=[ "Breakpoint commands:", "frame variable --show-types --scope" ]) self.expect("breakpoint command list 2", "Breakpoint 2 command ok", substrs=[ "Breakpoint commands (Python):", "import side_effect", "side_effect.one_liner" ]) self.expect("breakpoint command list 3", "Breakpoint 3 command ok", substrs=[ "Breakpoint commands (Python):", "bktptcmd.function(frame, bp_loc, internal_dict)" ]) self.expect("breakpoint command list 4", "Breakpoint 4 command ok", substrs=[ "Breakpoint commands:", "frame variable --show-types --scope" ]) self.runCmd("breakpoint delete 4") # Next lets try some other breakpoint kinds. First break with a regular expression # and then specify only one file. The first time we should get two locations, # the second time only one: lldbutil.run_break_set_by_regexp(self, r"._MyFunction", num_expected_locations=2) lldbutil.run_break_set_by_regexp(self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1) lldbutil.run_break_set_by_regexp(self, r"._MyFunction", extra_options="-f a.c -f b.c", num_expected_locations=2) # Now try a source regex breakpoint: lldbutil.run_break_set_by_source_regexp(self, r"is about to return [12]0", extra_options="-f a.c -f b.c", num_expected_locations=2) lldbutil.run_break_set_by_source_regexp(self, r"is about to return [12]0", extra_options="-f a.c", num_expected_locations=1) # Reset our canary variables and run the program. side_effect.one_liner = None side_effect.bktptcmd = None self.runCmd("run", RUN_SUCCEEDED) # Check the value of canary variables. self.assertEquals("one liner was here", side_effect.one_liner) self.assertEquals("function was here", side_effect.bktptcmd) # Finish the program. self.runCmd("process continue") # Remove the breakpoint command associated with breakpoint 1. self.runCmd("breakpoint command delete 1") # Remove breakpoint 2. self.runCmd("breakpoint delete 2") self.expect( "breakpoint command list 1", startstr="Breakpoint 1 does not have an associated command.") self.expect( "breakpoint command list 2", error=True, startstr="error: '2' is not a currently valid breakpoint ID.") # The breakpoint list now only contains breakpoint 1. self.expect( "breakpoint list -f", "Breakpoint 1 exists", patterns=[ "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" % self.line, "hit count = 1" ]) # Not breakpoint 2. self.expect( "breakpoint list -f", "No more breakpoint 2", matching=False, substrs=[ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" % self.line ]) # Run the program again, with breakpoint 1 remaining. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to breakpoint 1. # 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 2. lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=2)
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line, num_expected_locations=-1) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line2, num_expected_locations=-1) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line3, num_expected_locations=-1) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.line4, num_expected_locations=-1) self.runCmd("run", RUN_SUCCEEDED) lldbutil.skip_if_library_missing( self, self.target(), lldbutil.PrintableRegex("libc\+\+")) # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) self.runCmd( "settings set target.max-children-count 256", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.runCmd("frame variable numbers_list --show-types") self.runCmd( "type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e") self.runCmd("type format add -f hex int") self.expect("frame variable numbers_list --raw", matching=False, substrs=['list has 0 items', '{}']) self.expect("frame variable numbers_list", substrs=['list has 0 items', '{}']) self.expect("p numbers_list", substrs=['list has 0 items', '{}']) self.runCmd("n") # This gets up past the printf self.runCmd("n") # Now advance over the first push_back. self.expect("frame variable numbers_list", substrs=['list has 1 items', '[0] = ', '0x12345678']) self.runCmd("n") self.runCmd("n") self.runCmd("n") self.expect("frame variable numbers_list", substrs=['list has 4 items', '[0] = ', '0x12345678', '[1] =', '0x11223344', '[2] =', '0xbeeffeed', '[3] =', '0x00abba00']) self.runCmd("n") self.runCmd("n") self.expect("frame variable numbers_list", substrs=['list has 6 items', '[0] = ', '0x12345678', '0x11223344', '0xbeeffeed', '0x00abba00', '[4] =', '0x0abcdef0', '[5] =', '0x0cab0cab']) self.expect("p numbers_list", substrs=['list has 6 items', '[0] = ', '0x12345678', '0x11223344', '0xbeeffeed', '0x00abba00', '[4] =', '0x0abcdef0', '[5] =', '0x0cab0cab']) # check access-by-index self.expect("frame variable numbers_list[0]", substrs=['0x12345678']) self.expect("frame variable numbers_list[1]", substrs=['0x11223344']) self.runCmd("n") self.expect("frame variable numbers_list", substrs=['list has 0 items', '{}']) self.runCmd("n") self.runCmd("n") self.runCmd("n") self.runCmd("n") self.expect("frame variable numbers_list", substrs=['list has 4 items', '[0] = ', '1', '[1] = ', '2', '[2] = ', '3', '[3] = ', '4']) # check that MightHaveChildren() gets it right self.assertTrue( self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!") self.runCmd("type format delete int") self.runCmd("c") self.expect("frame variable text_list", substrs=['list has 3 items', '[0]', 'goofy', '[1]', 'is', '[2]', 'smart']) # check that MightHaveChildren() gets it right self.assertTrue( self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!") self.expect("p text_list", substrs=['list has 3 items', '\"goofy\"', '\"is\"', '\"smart\"']) self.runCmd("n") # This gets us past the printf self.runCmd("n") self.runCmd("n") # check access-by-index self.expect("frame variable text_list[0]", substrs=['goofy']) self.expect("frame variable text_list[3]", substrs=['!!!']) self.runCmd("continue") # check that the list provider correctly updates if elements move countingList = self.frame().FindVariable("countingList") countingList.SetPreferDynamicValue(True) countingList.SetPreferSyntheticValue(True) self.assertTrue(countingList.GetChildAtIndex( 0).GetValueAsUnsigned(0) == 3141, "list[0] == 3141") self.assertTrue(countingList.GetChildAtIndex( 1).GetValueAsUnsigned(0) == 3141, "list[1] == 3141") self.runCmd("continue") self.assertTrue( countingList.GetChildAtIndex(0).GetValueAsUnsigned(0) == 3141, "uniqued list[0] == 3141") self.assertTrue( countingList.GetChildAtIndex(1).GetValueAsUnsigned(0) == 3142, "uniqued list[1] == 3142")
def test_process_launch_for_universal(self): """Test process launch of a universal binary.""" from lldbsuite.test.lldbutil import print_registers # Invoke the default build rule. self.build() # Note that "testit" is a universal binary. exe = os.path.join(os.getcwd(), "testit") # By default, x86_64 is assumed if no architecture is specified. self.expect("file " + exe, CURRENT_EXECUTABLE_SET, startstr="Current executable set to ", substrs=["testit' (x86_64)."]) # Break inside the main. lldbutil.run_break_set_by_file_and_line(self, "main.c", self.line, num_expected_locations=1, loc_exact=True) # We should be able to launch the x86_64 executable. self.runCmd("run", RUN_SUCCEEDED) # Check whether we have a 64-bit process launched. target = self.dbg.GetSelectedTarget() process = target.GetProcess() self.assertTrue( target and process and self.invoke(process, 'GetAddressByteSize') == 8, "64-bit process launched") frame = process.GetThreadAtIndex(0).GetFrameAtIndex(0) registers = print_registers(frame, string_buffer=True) self.expect(registers, exe=False, substrs=['Name: rax']) self.runCmd("continue") # Now specify i386 as the architecture for "testit". self.expect("file -a i386 " + exe, CURRENT_EXECUTABLE_SET, startstr="Current executable set to ", substrs=["testit' (i386)."]) # Break inside the main. lldbutil.run_break_set_by_file_and_line(self, "main.c", self.line, num_expected_locations=1, loc_exact=True) # We should be able to launch the i386 executable as well. self.runCmd("run", RUN_SUCCEEDED) # Check whether we have a 32-bit process launched. target = self.dbg.GetSelectedTarget() process = target.GetProcess() self.assertTrue(target and process, "32-bit process launched") pointerSize = self.invoke(process, 'GetAddressByteSize') self.assertTrue( pointerSize == 4, "AddressByteSize of 32-bit process should be 4, got %d instead." % pointerSize) frame = process.GetThreadAtIndex(0).GetFrameAtIndex(0) registers = print_registers(frame, string_buffer=True) self.expect(registers, exe=False, substrs=['Name: eax']) self.runCmd("continue")
def test_with_run_command(self): """Test the SBData APIs.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", 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']) target = self.dbg.GetSelectedTarget() process = target.GetProcess() thread = lldbutil.get_stopped_thread( process, lldb.eStopReasonBreakpoint) self.assertIsNotNone(thread) frame = thread.GetSelectedFrame() if self.TraceOn(): print(frame) foobar = frame.FindVariable('foobar') self.assertTrue(foobar.IsValid()) if self.TraceOn(): print(foobar) data = foobar.GetPointeeData(0, 2) offset = 0 error = lldb.SBError() self.assert_data(data.GetUnsignedInt32, offset, 1) offset += 4 low = data.GetSignedInt16(error, offset) self.assertTrue(error.Success()) offset += 2 high = data.GetSignedInt16(error, offset) self.assertTrue(error.Success()) offset += 2 self.assertTrue( (low == 9 and high == 0) or ( low == 0 and high == 9), 'foo[0].b == 9') self.assertTrue( fabs( data.GetFloat( error, offset) - 3.14) < 1, 'foo[0].c == 3.14') self.assertTrue(error.Success()) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 8) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 5) offset += 4 self.runCmd("n") offset = 16 self.assert_data(data.GetUnsignedInt32, offset, 5) data = foobar.GetPointeeData(1, 1) offset = 0 self.assert_data(data.GetSignedInt32, offset, 8) offset += 4 self.assert_data(data.GetSignedInt32, offset, 7) offset += 8 self.assertTrue( data.GetUnsignedInt32( error, offset) == 0, 'do not read beyond end') self.assertTrue(not error.Success()) error.Clear() # clear the error for the next test star_foobar = foobar.Dereference() self.assertTrue(star_foobar.IsValid()) data = star_foobar.GetData() if self.TraceOn(): print(data) offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 1) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 9) foobar_addr = star_foobar.GetLoadAddress() foobar_addr += 12 # http://llvm.org/bugs/show_bug.cgi?id=11579 # lldb::SBValue::CreateValueFromAddress does not verify SBType::GetPointerType succeeds # This should not crash LLDB. nothing = foobar.CreateValueFromAddress( "nothing", foobar_addr, star_foobar.GetType().GetBasicType( lldb.eBasicTypeInvalid)) new_foobar = foobar.CreateValueFromAddress( "f00", foobar_addr, star_foobar.GetType()) self.assertTrue(new_foobar.IsValid()) if self.TraceOn(): print(new_foobar) data = new_foobar.GetData() if self.TraceOn(): print(data) self.assertTrue(data.uint32[0] == 8, 'then foo[1].a == 8') self.assertTrue(data.uint32[1] == 7, 'then foo[1].b == 7') # exploiting that sizeof(uint32) == sizeof(float) self.assertTrue(fabs(data.float[2] - 3.14) < 1, 'foo[1].c == 3.14') self.runCmd("n") offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 8) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 7) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 3.14) < 1, 'foo[1].c == 3.14') self.assertTrue(error.Success()) data = new_foobar.GetData() if self.TraceOn(): print(data) offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 8) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 7) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 6.28) < 1, 'foo[1].c == 6.28') self.assertTrue(error.Success()) self.runCmd("n") barfoo = frame.FindVariable('barfoo') data = barfoo.GetData() if self.TraceOn(): print(barfoo) if self.TraceOn(): print(data) offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 1) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 2) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 3) < 1, 'barfoo[0].c == 3') self.assertTrue(error.Success()) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 4) offset += 4 self.assert_data(data.GetUnsignedInt32, offset, 5) offset += 4 self.assertTrue( fabs( data.GetFloat( error, offset) - 6) < 1, 'barfoo[1].c == 6') self.assertTrue(error.Success()) new_object = barfoo.CreateValueFromData( "new_object", data, barfoo.GetType().GetBasicType( lldb.eBasicTypeInt)) if self.TraceOn(): print(new_object) self.assertTrue(new_object.GetValue() == "1", 'new_object == 1') if data.GetByteOrder() == lldb.eByteOrderBig: data.SetData( error, '\0\0\0A', data.GetByteOrder(), data.GetAddressByteSize()) else: data.SetData( error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize()) self.assertTrue(error.Success()) data2 = lldb.SBData() data2.SetData( error, 'BCD', data.GetByteOrder(), data.GetAddressByteSize()) self.assertTrue(error.Success()) data.Append(data2) if self.TraceOn(): print(data) # this breaks on EBCDIC offset = 0 self.assert_data(data.GetUnsignedInt32, offset, 65) offset += 4 self.assert_data(data.GetUnsignedInt8, offset, 66) offset += 1 self.assert_data(data.GetUnsignedInt8, offset, 67) offset += 1 self.assert_data(data.GetUnsignedInt8, offset, 68) offset += 1 # check the new API calls introduced per LLVM llvm.org/prenhancement request # 11619 (Allow creating SBData values from arrays or primitives in # Python) hello_str = "hello!" data2 = lldb.SBData.CreateDataFromCString( process.GetByteOrder(), process.GetAddressByteSize(), hello_str) self.assertTrue(len(data2.uint8) == len(hello_str)) self.assertTrue(data2.uint8[0] == 104, 'h == 104') self.assertTrue(data2.uint8[1] == 101, 'e == 101') self.assertTrue(data2.uint8[2] == 108, 'l == 108') self.assert_data(data2.GetUnsignedInt8, 3, 108) # l self.assertTrue(data2.uint8[4] == 111, 'o == 111') self.assert_data(data2.GetUnsignedInt8, 5, 33) # ! uint_lists = [[1, 2, 3, 4, 5], [int(i) for i in [1, 2, 3, 4, 5]]] int_lists = [[2, -2], [int(i) for i in [2, -2]]] for l in uint_lists: data2 = lldb.SBData.CreateDataFromUInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assert_data(data2.GetUnsignedInt64, 0, 1) self.assert_data(data2.GetUnsignedInt64, 8, 2) self.assert_data(data2.GetUnsignedInt64, 16, 3) self.assert_data(data2.GetUnsignedInt64, 24, 4) self.assert_data(data2.GetUnsignedInt64, 32, 5) self.assertTrue( data2.uint64s == [ 1, 2, 3, 4, 5], 'read_data_helper failure: data2 == [1,2,3,4,5]') for l in int_lists: data2 = lldb.SBData.CreateDataFromSInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assertTrue( data2.sint32[ 0:2] == [ 2, -2], 'signed32 data2 = [2,-2]') data2.Append( lldb.SBData.CreateDataFromSInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), int_lists[0])) self.assert_data(data2.GetSignedInt32, 0, 2) self.assert_data(data2.GetSignedInt32, 4, -2) self.assertTrue( data2.sint64[ 1:3] == [ 2, -2], 'signed64 data2 = [2,-2]') for l in int_lists: data2 = lldb.SBData.CreateDataFromSInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assert_data(data2.GetSignedInt64, 0, 2) self.assert_data(data2.GetSignedInt64, 8, -2) self.assertTrue( data2.sint64[ 0:2] == [ 2, -2], 'signed64 data2 = [2,-2]') for l in uint_lists: data2 = lldb.SBData.CreateDataFromUInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), l) self.assert_data(data2.GetUnsignedInt32, 0, 1) self.assert_data(data2.GetUnsignedInt32, 4, 2) self.assert_data(data2.GetUnsignedInt32, 8, 3) self.assert_data(data2.GetUnsignedInt32, 12, 4) self.assert_data(data2.GetUnsignedInt32, 16, 5) bool_list = [True, True, False, False, True, False] data2 = lldb.SBData.CreateDataFromSInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.sint32[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'signed32 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromUInt32Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.uint32[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'unsigned32 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromSInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.sint64[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'signed64 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromUInt64Array( process.GetByteOrder(), process.GetAddressByteSize(), bool_list) self.assertTrue( data2.uint64[ 0:6] == [ 1, 1, 0, 0, 1, 0], 'signed64 data2 = [1, 1, 0, 0, 1, 0]') data2 = lldb.SBData.CreateDataFromDoubleArray( process.GetByteOrder(), process.GetAddressByteSize(), [ 3.14, 6.28, 2.71]) self.assertTrue( fabs( data2.GetDouble( error, 0) - 3.14) < 0.5, 'double data2[0] = 3.14') self.assertTrue(error.Success()) self.assertTrue( fabs( data2.GetDouble( error, 8) - 6.28) < 0.5, 'double data2[1] = 6.28') self.assertTrue(error.Success()) self.assertTrue( fabs( data2.GetDouble( error, 16) - 2.71) < 0.5, 'double data2[2] = 2.71') self.assertTrue(error.Success()) data2 = lldb.SBData() data2.SetDataFromCString(hello_str) self.assertTrue(len(data2.uint8) == len(hello_str)) self.assert_data(data2.GetUnsignedInt8, 0, 104) self.assert_data(data2.GetUnsignedInt8, 1, 101) self.assert_data(data2.GetUnsignedInt8, 2, 108) self.assert_data(data2.GetUnsignedInt8, 3, 108) self.assert_data(data2.GetUnsignedInt8, 4, 111) self.assert_data(data2.GetUnsignedInt8, 5, 33) data2.SetDataFromUInt64Array([1, 2, 3, 4, 5]) self.assert_data(data2.GetUnsignedInt64, 0, 1) self.assert_data(data2.GetUnsignedInt64, 8, 2) self.assert_data(data2.GetUnsignedInt64, 16, 3) self.assert_data(data2.GetUnsignedInt64, 24, 4) self.assert_data(data2.GetUnsignedInt64, 32, 5) self.assertTrue( data2.uint64[0] == 1, 'read_data_helper failure: set data2[0] = 1') self.assertTrue( data2.uint64[1] == 2, 'read_data_helper failure: set data2[1] = 2') self.assertTrue( data2.uint64[2] == 3, 'read_data_helper failure: set data2[2] = 3') self.assertTrue( data2.uint64[3] == 4, 'read_data_helper failure: set data2[3] = 4') self.assertTrue( data2.uint64[4] == 5, 'read_data_helper failure: set data2[4] = 5') self.assertTrue( data2.uint64[ 0:2] == [ 1, 2], 'read_data_helper failure: set data2[0:2] = [1,2]') data2.SetDataFromSInt32Array([2, -2]) self.assert_data(data2.GetSignedInt32, 0, 2) self.assert_data(data2.GetSignedInt32, 4, -2) data2.SetDataFromSInt64Array([2, -2]) self.assert_data(data2.GetSignedInt64, 0, 2) self.assert_data(data2.GetSignedInt64, 8, -2) data2.SetDataFromUInt32Array([1, 2, 3, 4, 5]) self.assert_data(data2.GetUnsignedInt32, 0, 1) self.assert_data(data2.GetUnsignedInt32, 4, 2) self.assert_data(data2.GetUnsignedInt32, 8, 3) self.assert_data(data2.GetUnsignedInt32, 12, 4) self.assert_data(data2.GetUnsignedInt32, 16, 5) self.assertTrue( data2.uint32[0] == 1, 'read_data_helper failure: set 32-bit data2[0] = 1') self.assertTrue( data2.uint32[1] == 2, 'read_data_helper failure: set 32-bit data2[1] = 2') self.assertTrue( data2.uint32[2] == 3, 'read_data_helper failure: set 32-bit data2[2] = 3') self.assertTrue( data2.uint32[3] == 4, 'read_data_helper failure: set 32-bit data2[3] = 4') self.assertTrue( data2.uint32[4] == 5, 'read_data_helper failure: set 32-bit data2[4] = 5') data2.SetDataFromDoubleArray([3.14, 6.28, 2.71]) self.assertTrue(fabs(data2.GetDouble(error, 0) - 3.14) < 0.5, 'set double data2[0] = 3.14') self.assertTrue(fabs(data2.GetDouble(error, 8) - 6.28) < 0.5, 'set double data2[1] = 6.28') self.assertTrue(fabs(data2.GetDouble(error, 16) - 2.71) < 0.5, 'set double data2[2] = 2.71') self.assertTrue( fabs( data2.double[0] - 3.14) < 0.5, 'read_data_helper failure: set double data2[0] = 3.14') self.assertTrue( fabs( data2.double[1] - 6.28) < 0.5, 'read_data_helper failure: set double data2[1] = 6.28') self.assertTrue( fabs( data2.double[2] - 2.71) < 0.5, 'read_data_helper failure: set double data2[2] = 2.71')
def test_show_command(self): """Test 'mpx-table show' command""" self.build() plugin_file = os.path.join(configuration.lldb_libs_dir, "liblldbIntelFeatures.so") if not os.path.isfile(plugin_file): self.skipTest("features plugin missing.") plugin_command = " " seq = ("plugin", "load", plugin_file) plugin_command = plugin_command.join(seq) self.runCmd(plugin_command) exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) self.b1 = line_number('main.cpp', '// Break 1.') self.b2 = line_number('main.cpp', '// Break 2.') self.b3 = line_number('main.cpp', '// Break 3.') self.b4 = line_number('main.cpp', '// Break 4.') lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.b1, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.b2, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.b3, num_expected_locations=1) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.b4, num_expected_locations=1) self.runCmd("run", RUN_SUCCEEDED) target = self.dbg.GetSelectedTarget() process = target.GetProcess() if (process.GetState() == lldb.eStateExited): self.skipTest("Intel(R) MPX is not supported.") else: self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, substrs = ["stop reason = breakpoint 1."]) self.expect("mpx-table show a", substrs = ['lbound = 0x', ', ubound = 0x', '(pointer value = 0x', ', metadata = 0x', ')'], error = False) self.expect("continue", STOPPED_DUE_TO_BREAKPOINT, substrs = ["stop reason = breakpoint 2."]) # Check that out of scope pointer cannot be reached. # self.expect("mpx-table show a", substrs = ['Invalid pointer.'], error = True) self.expect("mpx-table show tmp", substrs = ['lbound = 0x', ', ubound = 0x', '(pointer value = 0x', ', metadata = 0x', ')'], error = False) self.expect("continue", STOPPED_DUE_TO_BREAKPOINT, substrs = ["stop reason = breakpoint 3."]) # Check that the pointer value is correctly updated. # self.expect("mpx-table show tmp", substrs = ['lbound = 0x', ', ubound = 0x', '(pointer value = 0x2', ', metadata = 0x', ')'], error = False) self.expect("continue", STOPPED_DUE_TO_BREAKPOINT, substrs = ["stop reason = breakpoint 4."]) # After going back to main(), check that out of scope pointer cannot be # reached. # self.expect("mpx-table show tmp", substrs = ['Invalid pointer.'], error = True) self.expect("mpx-table show a", substrs = ['lbound = 0x', ', ubound = 0x', '(pointer value = 0x', ', metadata = 0x', ')'], error = False)
def test(self): """Test that the C++11 support for char16_t and char32_t works correctly.""" self.build() exe = self.getBuildArtifact("a.out") # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set breakpoints for line in self.lines: lldbutil.run_break_set_by_file_and_line(self, "main.cpp", line) # Now launch the process, and do not stop at entry point and stop at # breakpoint1 process = target.LaunchSimple( None, None, self.get_process_working_directory()) if not process: self.fail("SBTarget.Launch() failed") if self.TraceOn(): self.runCmd("frame variable") # Check that we correctly report the const types self.expect( "frame variable cs16 cs32", substrs=[ '(const char16_t *) cs16 = ', 'u"hello world ྒྙྐ"', '(const char32_t *) cs32 = ', 'U"hello world ྒྙྐ"']) # Check that we correctly report the non-const types self.expect( "frame variable s16 s32", substrs=[ '(char16_t *) s16 = ', 'u"ﺸﺵۻ"', '(char32_t *) s32 = ', 'U"ЕЙРГЖО"']) # Check that we correctly report the array types self.expect( "frame variable as16 as32", patterns=[ '\(char16_t\[[0-9]+\]\) as16 = ', '\(char32_t\[[0-9]+\]\) as32 = '], substrs=[ 'u"ﺸﺵۻ"', 'U"ЕЙРГЖО"']) self.runCmd("next") # step to after the string is nullified # check that we don't crash on NULL self.expect("frame variable s32", substrs=['(char32_t *) s32 = 0x00000000']) # continue and hit breakpoint2 self.runCmd("continue") # check that the new strings show self.expect( "frame variable s16 s32", substrs=[ '(char16_t *) s16 = 0x', '"色ハ匂ヘト散リヌルヲ"', '(char32_t *) s32 = ', '"෴"']) # check the same as above for arrays self.expect( "frame variable as16 as32", patterns=[ '\(char16_t\[[0-9]+\]\) as16 = ', '\(char32_t\[[0-9]+\]\) as32 = '], substrs=[ '"色ハ匂ヘト散リヌルヲ"', '"෴"']) # check that zero values are properly handles self.expect_expr('cs16_zero', result_summary="U+0000 u'\\0'") self.expect_expr('cs32_zero', result_summary="U+0x00000000 U'\\0'") # Check that we can run expressions that return charN_t self.expect_expr("u'a'", result_type="char16_t", result_summary="U+0061 u'a'") self.expect_expr("U'a'", result_type="char32_t", result_summary="U+0x00000061 U'a'")
def test_formatters_api(self): """Test Python APIs for working with formatters""" self.build() self.setTearDownCleanup() """Test Python APIs for working with formatters""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synthetic clear', check=False) self.runCmd('type category delete foobar', check=False) self.runCmd('type category delete JASSynth', check=False) self.runCmd('type category delete newbar', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) format = lldb.SBTypeFormat(lldb.eFormatHex) category = self.dbg.GetDefaultCategory() category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"), format) self.expect("frame variable foo.A", substrs=['0x00000001']) self.expect("frame variable foo.E", matching=False, substrs=['b8cca70a']) category.AddTypeFormat(lldb.SBTypeNameSpecifier("long"), format) self.expect("frame variable foo.A", substrs=['0x00000001']) self.expect("frame variable foo.E", substrs=['b8cca70a']) format.format = lldb.eFormatOctal category.AddTypeFormat(lldb.SBTypeNameSpecifier("int"), format) self.expect("frame variable foo.A", substrs=['01']) self.expect("frame variable foo.E", substrs=['b8cca70a']) category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("int")) category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("long")) self.expect("frame variable foo.A", matching=False, substrs=['01']) self.expect("frame variable foo.E", matching=False, substrs=['b8cca70a']) summary = lldb.SBTypeSummary.CreateWithSummaryString( "the hello world you'll never see") summary.SetSummaryString('hello world') new_category = self.dbg.GetCategory("foobar") self.assertFalse(new_category.IsValid(), "getting a non-existing category worked") new_category = self.dbg.CreateCategory("foobar") new_category.enabled = True new_category.AddTypeSummary(lldb.SBTypeNameSpecifier("^.*t$", True), summary) self.expect("frame variable foo.A", substrs=['hello world']) self.expect("frame variable foo.E", matching=False, substrs=['hello world']) self.expect("frame variable foo.B", substrs=['hello world']) self.expect("frame variable foo.F", substrs=['hello world']) new_category.enabled = False self.expect("frame variable foo.A", matching=False, substrs=['hello world']) self.expect("frame variable foo.E", matching=False, substrs=['hello world']) self.expect("frame variable foo.B", matching=False, substrs=['hello world']) self.expect("frame variable foo.F", matching=False, substrs=['hello world']) self.dbg.DeleteCategory(new_category.GetName()) self.expect("frame variable foo.A", matching=False, substrs=['hello world']) self.expect("frame variable foo.E", matching=False, substrs=['hello world']) self.expect("frame variable foo.B", matching=False, substrs=['hello world']) self.expect("frame variable foo.F", matching=False, substrs=['hello world']) filter = lldb.SBTypeFilter(0) filter.AppendExpressionPath("A") filter.AppendExpressionPath("D") self.assertTrue(filter.GetNumberOfExpressionPaths() == 2, "filter with two items does not have two items") category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) self.expect("frame variable foo", substrs=['A = 1', 'D = 6.28']) self.expect("frame variable foo", matching=False, substrs=['B = ', 'C = ', 'E = ', 'F = ']) category.DeleteTypeFilter(lldb.SBTypeNameSpecifier( "JustAStruct", True)) self.expect("frame variable foo", substrs=['A = 1', 'D = 6.28']) self.expect("frame variable foo", matching=False, substrs=['B = ', 'C = ', 'E = ', 'F = ']) category.DeleteTypeFilter( lldb.SBTypeNameSpecifier("JustAStruct", False)) self.expect("frame variable foo", substrs=['A = 1', 'D = 6.28']) self.expect("frame variable foo", matching=True, substrs=['B = ', 'C = ', 'E = ', 'F = ']) self.runCmd("command script import --allow-reload ./synth.py") self.expect("frame variable foo", matching=False, substrs=['X = 1']) self.dbg.GetCategory("JASSynth").SetEnabled(True) self.expect("frame variable foo", matching=True, substrs=['X = 1']) self.dbg.GetCategory("CCCSynth").SetEnabled(True) self.expect("frame variable ccc", matching=True, substrs=[ 'CCC object with leading value (int) a = 111', 'a = 111', 'b = 222', 'c = 333' ]) foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame().FindVariable('foo') self.assertTrue(foo_var.IsValid(), 'could not find foo') self.assertTrue(foo_var.GetDeclaration().IsValid(), 'foo declaration is invalid') self.assertTrue( foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (synth)') self.assertTrue( foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 1, 'foo_synth.X has wrong value (synth)') self.assertFalse( foo_var.GetChildMemberWithName('B').IsValid(), 'foo_synth.B is valid but should not (synth)') self.dbg.GetCategory("JASSynth").SetEnabled(False) foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame().FindVariable('foo') self.assertTrue(foo_var.IsValid(), 'could not find foo') self.assertFalse(foo_var.GetNumChildren() == 2, 'still seeing synthetic value') filter = lldb.SBTypeFilter(0) filter.AppendExpressionPath("A") filter.AppendExpressionPath("D") category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) self.expect("frame variable foo", substrs=['A = 1', 'D = 6.28']) foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame().FindVariable('foo') self.assertTrue(foo_var.IsValid(), 'could not find foo') self.assertTrue( foo_var.GetNumChildren() == 2, 'synthetic value has wrong number of child items (filter)') self.assertTrue( foo_var.GetChildMemberWithName('X').GetValueAsUnsigned() == 0, 'foo_synth.X has wrong value (filter)') self.assertTrue( foo_var.GetChildMemberWithName('A').GetValueAsUnsigned() == 1, 'foo_synth.A has wrong value (filter)') self.assertTrue(filter.ReplaceExpressionPathAtIndex(0, "C"), "failed to replace an expression path in filter") self.expect("frame variable foo", substrs=['A = 1', 'D = 6.28']) category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) self.expect("frame variable foo", substrs=["C = 'e'", 'D = 6.28']) category.AddTypeFilter(lldb.SBTypeNameSpecifier("FooType"), filter) filter.ReplaceExpressionPathAtIndex(1, "F") self.expect("frame variable foo", substrs=["C = 'e'", 'D = 6.28']) category.AddTypeFilter(lldb.SBTypeNameSpecifier("JustAStruct"), filter) self.expect("frame variable foo", substrs=["C = 'e'", 'F = 0']) self.expect("frame variable bar", substrs=["C = 'e'", 'D = 6.28']) foo_var = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame().FindVariable('foo') self.assertTrue(foo_var.IsValid(), 'could not find foo') self.assertTrue( foo_var.GetChildMemberWithName('C').GetValueAsUnsigned() == ord( 'e'), 'foo_synth.C has wrong value (filter)') chosen = self.dbg.GetFilterForType( lldb.SBTypeNameSpecifier("JustAStruct")) self.assertTrue(chosen.count == 2, "wrong filter found for JustAStruct") self.assertTrue( chosen.GetExpressionPathAtIndex(0) == 'C', "wrong item at index 0 for JustAStruct") self.assertTrue( chosen.GetExpressionPathAtIndex(1) == 'F', "wrong item at index 1 for JustAStruct") self.assertFalse( category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("NoSuchType")), "deleting a non-existing filter worked") self.assertFalse( category.DeleteTypeSummary(lldb.SBTypeNameSpecifier("NoSuchType")), "deleting a non-existing summary worked") self.assertFalse( category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("NoSuchType")), "deleting a non-existing format worked") self.assertFalse( category.DeleteTypeSynthetic( lldb.SBTypeNameSpecifier("NoSuchType")), "deleting a non-existing synthetic worked") self.assertFalse( category.DeleteTypeFilter(lldb.SBTypeNameSpecifier("")), "deleting a filter for '' worked") self.assertFalse( category.DeleteTypeSummary(lldb.SBTypeNameSpecifier("")), "deleting a summary for '' worked") self.assertFalse( category.DeleteTypeFormat(lldb.SBTypeNameSpecifier("")), "deleting a format for '' worked") self.assertFalse( category.DeleteTypeSynthetic(lldb.SBTypeNameSpecifier("")), "deleting a synthetic for '' worked") try: self.assertFalse( category.AddTypeSummary( lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a summary valued None worked") except: pass else: self.assertFalse(True, "adding a summary valued None worked") try: self.assertFalse( category.AddTypeFilter( lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a filter valued None worked") except: pass else: self.assertFalse(True, "adding a filter valued None worked") try: self.assertFalse( category.AddTypeSynthetic( lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a synthetic valued None worked") except: pass else: self.assertFalse(True, "adding a synthetic valued None worked") try: self.assertFalse( category.AddTypeFormat( lldb.SBTypeNameSpecifier("NoneSuchType"), None), "adding a format valued None worked") except: pass else: self.assertFalse(True, "adding a format valued None worked") self.assertFalse( category.AddTypeSummary(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeSummary()), "adding a summary without value worked") self.assertFalse( category.AddTypeFilter(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeFilter()), "adding a filter without value worked") self.assertFalse( category.AddTypeSynthetic( lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeSynthetic()), "adding a synthetic without value worked") self.assertFalse( category.AddTypeFormat(lldb.SBTypeNameSpecifier("EmptySuchType"), lldb.SBTypeFormat()), "adding a format without value worked") self.assertFalse( category.AddTypeSummary( lldb.SBTypeNameSpecifier(""), lldb.SBTypeSummary.CreateWithSummaryString("")), "adding a summary for an invalid type worked") self.assertFalse( category.AddTypeFilter(lldb.SBTypeNameSpecifier(""), lldb.SBTypeFilter(0)), "adding a filter for an invalid type worked") self.assertFalse( category.AddTypeSynthetic( lldb.SBTypeNameSpecifier(""), lldb.SBTypeSynthetic.CreateWithClassName("")), "adding a synthetic for an invalid type worked") self.assertFalse( category.AddTypeFormat(lldb.SBTypeNameSpecifier(""), lldb.SBTypeFormat(lldb.eFormatHex)), "adding a format for an invalid type worked") new_category = self.dbg.CreateCategory("newbar") new_category.AddTypeSummary( lldb.SBTypeNameSpecifier("JustAStruct"), lldb.SBTypeSummary.CreateWithScriptCode( "return 'hello scripted world';")) self.expect("frame variable foo", matching=False, substrs=['hello scripted world']) new_category.enabled = True self.expect("frame variable foo", matching=True, substrs=['hello scripted world']) self.expect("frame variable foo_ptr", matching=True, substrs=['hello scripted world']) new_category.AddTypeSummary( lldb.SBTypeNameSpecifier("JustAStruct"), lldb.SBTypeSummary.CreateWithScriptCode( "return 'hello scripted world';", lldb.eTypeOptionSkipPointers)) self.expect("frame variable foo", matching=True, substrs=['hello scripted world']) frame = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame() foo_ptr = frame.FindVariable("foo_ptr") summary = foo_ptr.GetTypeSummary() self.assertFalse(summary.IsValid(), "summary found for foo* when none was planned") self.expect("frame variable foo_ptr", matching=False, substrs=['hello scripted world']) new_category.AddTypeSummary( lldb.SBTypeNameSpecifier("JustAStruct"), lldb.SBTypeSummary.CreateWithSummaryString("hello static world", lldb.eTypeOptionNone)) summary = foo_ptr.GetTypeSummary() self.assertTrue(summary.IsValid(), "no summary found for foo* when one was in place") self.assertTrue(summary.GetData() == "hello static world", "wrong summary found for foo*") self.expect("frame variable e1", substrs=["I am an empty Empty1 {}"]) self.expect("frame variable e2", substrs=["I am an empty Empty2"]) self.expect("frame variable e2", substrs=["I am an empty Empty2 {}"], matching=False)
def test_modify_source_file_while_debugging(self): """Modify a source file while debugging the executable.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, "main-copy.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', 'main-copy.c:%d' % self.line, 'stop reason = breakpoint' ]) # Display some source code. self.expect("source list -f main-copy.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY, substrs=['Hello world']) # Do the same thing with a file & line spec: self.expect("source list -y main-copy.c:%d" % self.line, SOURCE_DISPLAYED_CORRECTLY, substrs=['Hello world']) # The '-b' option shows the line table locations from the debug information # that indicates valid places to set source level breakpoints. # The file to display is implicit in this case. self.runCmd("source list -l %d -c 3 -b" % self.line) output = self.res.GetOutput().splitlines()[0] # If the breakpoint set command succeeded, we should expect a positive number # of breakpoints for the current line, i.e., self.line. import re m = re.search('^\[(\d+)\].*// Set break point at this line.', output) if not m: self.fail("Fail to display source level breakpoints") self.assertTrue(int(m.group(1)) > 0) # Read the main.c file content. with io.open(self.file, 'r', newline='\n') as f: original_content = f.read() if self.TraceOn(): print("original content:", original_content) # Modify the in-memory copy of the original source code. new_content = original_content.replace('Hello world', 'Hello lldb', 1) # Modify the source code file. with io.open(self.file, 'w', newline='\n') as f: time.sleep(1) f.write(new_content) if self.TraceOn(): print("new content:", new_content) print("os.path.getmtime() after writing new content:", os.path.getmtime(self.file)) # Display the source code again. We should see the updated line. self.expect("source list -f main-copy.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY, substrs=['Hello lldb'])
def run_lldb_process_load_and_unload_commands(self): """Test that lldb process load/unload command work correctly.""" self.copy_shlibs_to_remote() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break at main.cpp before the call to dlopen(). # Use lldb's process load command to load the dylib, instead. lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) ctx = self.platformContext dylibName = ctx.shlib_prefix + 'loadunload_a.' + ctx.shlib_extension localDylibPath = self.getBuildArtifact(dylibName) if lldb.remote_platform: wd = lldb.remote_platform.GetWorkingDirectory() remoteDylibPath = lldbutil.join_remote_paths(wd, dylibName) else: remoteDylibPath = localDylibPath # Make sure that a_function does not exist at this point. self.expect("image lookup -n a_function", "a_function should not exist yet", error=True, matching=False, patterns=["1 match found"]) # Use lldb 'process load' to load the dylib. self.expect("process load %s --install=%s" % (localDylibPath, remoteDylibPath), "%s loaded correctly" % dylibName, patterns=[ 'Loading "%s".*ok' % re.escape(localDylibPath), 'Image [0-9]+ loaded' ]) # Search for and match the "Image ([0-9]+) loaded" pattern. output = self.res.GetOutput() pattern = re.compile("Image ([0-9]+) loaded") for l in output.split(os.linesep): #print("l:", l) match = pattern.search(l) if match: break index = match.group(1) # Now we should have an entry for a_function. self.expect("image lookup -n a_function", "a_function should now exist", patterns=["1 match found .*%s" % dylibName]) # Use lldb 'process unload' to unload the dylib. self.expect("process unload %s" % index, "%s unloaded correctly" % dylibName, patterns=["Unloading .* with index %s.*ok" % index]) self.runCmd("process continue")
def set_breakpoint(self, line): lldbutil.run_break_set_by_file_and_line(self, "main.c", line, num_expected_locations=1, loc_exact=True)
def test_setpgid(self): self.build() exe = os.path.join(os.getcwd(), 'a.out') # Use a file as a synchronization point between test and inferior. pid_file_path = lldbutil.append_to_process_working_directory( "pid_file_%d" % (int(time.time()))) self.addTearDownHook( lambda: self.run_platform_command("rm %s" % (pid_file_path))) popen = self.spawnSubprocess(exe, [pid_file_path]) self.addTearDownHook(self.cleanupSubprocesses) max_attempts = 5 for i in range(max_attempts): err, retcode, msg = self.run_platform_command("ls %s" % pid_file_path) if err.Success() and retcode == 0: break else: print(msg) if i < max_attempts: # Exponential backoff! time.sleep(pow(2, i) * 0.30) else: self.fail("Child PID file %s not found even after %d attempts." % (pid_file_path, max_attempts)) err, retcode, pid = self.run_platform_command("cat %s" % (pid_file_path)) self.assertTrue( err.Success() and retcode == 0, "Failed to read file %s: %s, retcode: %d" % (pid_file_path, err.GetCString(), retcode)) # make sure we cleanup the forked child also def cleanupChild(): if lldb.remote_platform: lldb.remote_platform.Kill(int(pid)) else: if os.path.exists("/proc/" + pid): os.kill(int(pid), signal.SIGKILL) self.addTearDownHook(cleanupChild) # Create a target by the debugger. target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) listener = lldb.SBListener("my.attach.listener") error = lldb.SBError() process = target.AttachToProcessWithID(listener, int(pid), error) self.assertTrue(error.Success() and process, PROCESS_IS_VALID) # set a breakpoint just before the setpgid() call lldbutil.run_break_set_by_file_and_line(self, 'main.c', self.line, num_expected_locations=-1) thread = process.GetSelectedThread() # release the child from its loop value = thread.GetSelectedFrame().EvaluateExpression( "release_child_flag = 1") self.assertTrue(value.IsValid() and value.GetValueAsUnsigned(0) == 1) process.Continue() # make sure the child's process group id is different from its pid value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)") self.assertTrue(value.IsValid()) self.assertNotEqual(value.GetValueAsUnsigned(0), int(pid)) # step over the setpgid() call thread.StepOver() self.assertEqual(thread.GetStopReason(), lldb.eStopReasonPlanComplete) # verify that the process group has been set correctly # this also checks that we are still in full control of the child value = thread.GetSelectedFrame().EvaluateExpression("(int)getpgid(0)") self.assertTrue(value.IsValid()) self.assertEqual(value.GetValueAsUnsigned(0), int(pid)) # run to completion process.Continue() self.assertEqual(process.GetState(), lldb.eStateExited)
def test(self): """Test target.move-to-nearest logic""" self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) lldbutil.run_break_set_by_symbol(self, 'main', sym_exact=True) environment = self.registerSharedLibrariesWithTarget(target, ["foo"]) process = target.LaunchSimple(None, environment, self.get_process_working_directory()) self.assertEquals(process.GetState(), lldb.eStateStopped) # Regardless of the -m value the breakpoint should have exactly one # location on the foo functions self.runCmd("settings set target.move-to-nearest-code true") lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line1, loc_exact=True, extra_options="-m 1") lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line2, loc_exact=True, extra_options="-m 1") self.runCmd("settings set target.move-to-nearest-code false") lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line1, loc_exact=True, extra_options="-m 0") lldbutil.run_break_set_by_file_and_line(self, 'foo.h', self.line2, loc_exact=True, extra_options="-m 0") # Make sure we set a breakpoint in main with -m 1 for various lines in # the function declaration # "int" lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', self.line_main-1, extra_options="-m 1") # "main()" lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', self.line_main, extra_options="-m 1") # "{" lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', self.line_main+1, extra_options="-m 1") # "return .." lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', self.line_main+2, extra_options="-m 1")
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # Pick some values and check that the basics work self.runCmd("type filter add BagOfInts --child x --child z") self.expect("frame variable int_bag", substrs=['x = 6', 'z = 8']) # Check we can still access the missing child by summary self.runCmd( "type summary add BagOfInts --summary-string \"y=${var.y}\"") self.expect('frame variable int_bag', substrs=['y=7']) # Even if we have synth children, the summary prevails self.expect("frame variable int_bag", matching=False, substrs=['x = 6', 'z = 8']) # if we skip synth and summary show y self.expect( "frame variable int_bag --synthetic-type false --no-summary-depth=1", substrs=[ 'x = 6', 'y = 7', 'z = 8']) # if we ask for raw output same happens self.expect("frame variable int_bag --raw-output", substrs=['x = 6', 'y = 7', 'z = 8']) # Summary+Synth must work together self.runCmd( "type summary add BagOfInts --summary-string \"x=${var.x}\" -e") self.expect('frame variable int_bag', substrs=['x=6', 'x = 6', 'z = 8']) # Same output, but using Python self.runCmd( "type summary add BagOfInts --python-script \"return 'x=%s' % valobj.GetChildMemberWithName('x').GetValue()\" -e") self.expect('frame variable int_bag', substrs=['x=6', 'x = 6', 'z = 8']) # If I skip summaries, still give me the artificial children self.expect("frame variable int_bag --no-summary-depth=1", substrs=['x = 6', 'z = 8']) # Delete synth and check that the view reflects it immediately self.runCmd("type filter delete BagOfInts") self.expect("frame variable int_bag", substrs=['x = 6', 'y = 7', 'z = 8']) # Add the synth again and check that it's honored deeper in the # hierarchy self.runCmd("type filter add BagOfInts --child x --child z") self.expect('frame variable bag_bag', substrs=['x = x=69 {', 'x = 69', 'z = 71', 'y = x=66 {', 'x = 66', 'z = 68']) self.expect('frame variable bag_bag', matching=False, substrs=['y = 70', 'y = 67']) # Check that a synth can expand nested stuff self.runCmd("type filter add BagOfBags --child x.y --child y.z") self.expect('frame variable bag_bag', substrs=['x.y = 70', 'y.z = 68']) # ...even if we get -> and . wrong self.runCmd("type filter add BagOfBags --child x.y --child \"y->z\"") self.expect('frame variable bag_bag', substrs=['x.y = 70', 'y->z = 68']) # ...even bitfields self.runCmd( "type filter add BagOfBags --child x.y --child \"y->z[1-2]\"") self.expect('frame variable bag_bag --show-types', substrs=['x.y = 70', '(int:2) y->z[1-2] = 2']) # ...even if we format the bitfields self.runCmd( "type filter add BagOfBags --child x.y --child \"y->y[0-0]\"") self.runCmd("type format add \"int:1\" -f bool") self.expect('frame variable bag_bag --show-types', substrs=['x.y = 70', '(int:1) y->y[0-0] = true']) # ...even if we use one-liner summaries self.runCmd("type summary add -c BagOfBags") self.expect('frame variable bag_bag', substrs=[ '(BagOfBags) bag_bag = (x.y = 70, y->y[0-0] = true)']) self.runCmd("type summary delete BagOfBags") # now check we are dynamic (and arrays work) self.runCmd( "type filter add Plenty --child bitfield --child array[0] --child array[2]") self.expect('frame variable plenty_of_stuff', substrs=['bitfield = 1', 'array[0] = 5', 'array[2] = 3']) self.runCmd("n") self.expect('frame variable plenty_of_stuff', substrs=['bitfield = 17', 'array[0] = 5', 'array[2] = 3']) # skip synthetic children self.expect('frame variable plenty_of_stuff --synthetic-type no', substrs=['some_values = 0x', 'array = 0x', 'array_size = 5']) # check flat printing with synthetic children self.expect('frame variable plenty_of_stuff --flat', substrs=['plenty_of_stuff.bitfield = 17', '*(plenty_of_stuff.array) = 5', '*(plenty_of_stuff.array) = 3']) # check that we do not lose location information for our children self.expect('frame variable plenty_of_stuff --location', substrs=['0x', ': bitfield = 17']) # check we work across pointer boundaries self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1', substrs=['(BagOfInts *) plenty_of_stuff.some_values', 'x = 5', 'z = 7']) # but not if we don't want to self.runCmd("type filter add BagOfInts --child x --child z -p") self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1', substrs=['(BagOfInts *) plenty_of_stuff.some_values', 'x = 5', 'y = 6', 'z = 7']) # check we're dynamic even if nested self.runCmd("type filter add BagOfBags --child x.z") self.expect('frame variable bag_bag', substrs=['x.z = 71']) self.runCmd("n") self.expect('frame variable bag_bag', substrs=['x.z = 12']) self.runCmd( 'type summary add -e -s "I am always empty but have" EmptyStruct') self.expect('frame variable es', substrs=[ "I am always empty but have {}"]) self.runCmd('type summary add -e -h -s "I am really empty" EmptyStruct') self.expect('frame variable es', substrs=["I am really empty"]) self.expect( 'frame variable es', substrs=["I am really empty {}"], matching=False)
def test_data_type_and_expr(self): """Lookup objective-c data types and evaluate expressions.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Stop at -[MyString description]. lldbutil.run_break_set_by_symbol(self, '-[MyString description]', num_expected_locations=1, sym_exact=True) # self.expect("breakpoint set -n '-[MyString description]", BREAKPOINT_CREATED, # startstr = "Breakpoint created: 1: name = '-[MyString description]', # locations = 1") self.runCmd("run", RUN_SUCCEEDED) # The backtrace should show we stop at -[MyString description]. self.expect("thread backtrace", "Stop at -[MyString description]", substrs=["a.out`-[MyString description]"]) # Lookup objc data type MyString and evaluate some expressions. self.expect("image lookup -t NSString", DATA_TYPES_DISPLAYED_CORRECTLY, substrs=[ 'name = "NSString"', 'compiler_type = "@interface NSString' ]) self.expect("image lookup -t MyString", DATA_TYPES_DISPLAYED_CORRECTLY, substrs=[ 'name = "MyString"', 'compiler_type = "@interface MyString', 'NSString * str;', 'NSDate * date;' ]) self.expect("frame variable --show-types --scope", VARIABLES_DISPLAYED_CORRECTLY, substrs=["ARG: (MyString *) self"], patterns=["ARG: \(.*\) _cmd", "(objc_selector *)|(SEL)"]) # rdar://problem/8651752 # don't crash trying to ask clang how many children an empty record has self.runCmd("frame variable *_cmd") # rdar://problem/8492646 # test/foundation fails after updating to tot r115023 # self->str displays nothing as output self.expect("frame variable --show-types self->str", VARIABLES_DISPLAYED_CORRECTLY, startstr="(NSString *) self->str") # rdar://problem/8447030 # 'frame variable self->date' displays the wrong data member self.expect("frame variable --show-types self->date", VARIABLES_DISPLAYED_CORRECTLY, startstr="(NSDate *) self->date") # This should display the str and date member fields as well. self.expect("frame variable --show-types *self", VARIABLES_DISPLAYED_CORRECTLY, substrs=[ "(MyString) *self", "(NSString *) str", "(NSDate *) date" ]) # isa should be accessible. self.expect("expression self->isa", VARIABLES_DISPLAYED_CORRECTLY, substrs=["(Class)"]) # This should fail expectedly. self.expect( "expression self->non_existent_member", COMMAND_FAILED_AS_EXPECTED, error=True, startstr= "error: 'MyString' does not have a member named 'non_existent_member'" ) # Use expression parser. self.runCmd("expression self->str") self.runCmd("expression self->date") # (lldb) expression self->str # error: instance variable 'str' is protected # error: 1 errors parsing expression # # (lldb) expression self->date # error: instance variable 'date' is protected # error: 1 errors parsing expression # self.runCmd("breakpoint delete 1") lldbutil.run_break_set_by_file_and_line(self, "main.m", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("process continue") # rdar://problem/8542091 # test/foundation: expr -o -- my not working? # # Test new feature with r115115: # Add "-o" option to "expression" which prints the object description # if available. self.expect("expression --object-description -- my", "Object description displayed correctly", patterns=["Hello from.*a.out.*with timestamp: "])
def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case (most of these categories do not # exist anymore, but we just make sure we delete all of them) def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type category delete Category1', check=False) self.runCmd('type category delete Category2', check=False) self.runCmd('type category delete NewCategory', check=False) self.runCmd("type category delete CircleCategory", check=False) self.runCmd("type category delete RectangleStarCategory", check=False) self.runCmd("type category delete BaseCategory", check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # Add a summary to a new category and check that it works self.runCmd( "type summary add Rectangle --summary-string \"ARectangle\" -w NewCategory" ) self.expect( "frame variable r1 r2 r3", matching=False, substrs=['r1 = ARectangle', 'r2 = ARectangle', 'r3 = ARectangle']) self.runCmd("type category enable NewCategory") self.expect( "frame variable r1 r2 r3", matching=True, substrs=['r1 = ARectangle', 'r2 = ARectangle', 'r3 = ARectangle']) # Disable the category and check that the old stuff is there self.runCmd("type category disable NewCategory") self.expect("frame variable r1 r2 r3", substrs=['r1 = {', 'r2 = {', 'r3 = {']) # Re-enable the category and check that it works self.runCmd("type category enable NewCategory") self.expect( "frame variable r1 r2 r3", substrs=['r1 = ARectangle', 'r2 = ARectangle', 'r3 = ARectangle']) # Delete the category and the old stuff should be there self.runCmd("type category delete NewCategory") self.expect("frame variable r1 r2 r3", substrs=['r1 = {', 'r2 = {', 'r3 = {']) # Add summaries to two different categories and check that we can # switch self.runCmd( "type summary add --summary-string \"Width = ${var.w}, Height = ${var.h}\" Rectangle -w Category1" ) self.runCmd( "type summary add --python-script \"return 'Area = ' + str( int(valobj.GetChildMemberWithName('w').GetValue()) * int(valobj.GetChildMemberWithName('h').GetValue()) );\" Rectangle -w Category2" ) # check that enable A B is the same as enable B enable A self.runCmd("type category enable Category1 Category2") self.expect( "frame variable r1 r2 r3", substrs=['r1 = Width = ', 'r2 = Width = ', 'r3 = Width = ']) self.runCmd("type category disable Category1") self.expect("frame variable r1 r2 r3", substrs=['r1 = Area = ', 'r2 = Area = ', 'r3 = Area = ']) # switch again self.runCmd("type category enable Category1") self.expect( "frame variable r1 r2 r3", substrs=['r1 = Width = ', 'r2 = Width = ', 'r3 = Width = ']) # Re-enable the category and show that the preference is persisted self.runCmd("type category disable Category2") self.runCmd("type category enable Category2") self.expect("frame variable r1 r2 r3", substrs=['r1 = Area = ', 'r2 = Area = ', 'r3 = Area = ']) # Now delete the favorite summary self.runCmd("type summary delete Rectangle -w Category2") self.expect( "frame variable r1 r2 r3", substrs=['r1 = Width = ', 'r2 = Width = ', 'r3 = Width = ']) # Delete the summary from the default category (that does not have it) self.runCmd("type summary delete Rectangle", check=False) self.expect( "frame variable r1 r2 r3", substrs=['r1 = Width = ', 'r2 = Width = ', 'r3 = Width = ']) # Now add another summary to another category and switch back and forth self.runCmd("type category delete Category1 Category2") self.runCmd( "type summary add Rectangle -w Category1 --summary-string \"Category1\"" ) self.runCmd( "type summary add Rectangle -w Category2 --summary-string \"Category2\"" ) self.runCmd("type category enable Category2") self.runCmd("type category enable Category1") self.runCmd("type summary list -w Category1") self.expect("type summary list -w NoSuchCategoryHere", substrs=['no matching results found']) self.expect( "frame variable r1 r2 r3", substrs=['r1 = Category1', 'r2 = Category1', 'r3 = Category1']) self.runCmd("type category disable Category1") self.expect( "frame variable r1 r2 r3", substrs=['r1 = Category2', 'r2 = Category2', 'r3 = Category2']) # Check that re-enabling an enabled category works self.runCmd("type category enable Category1") self.expect( "frame variable r1 r2 r3", substrs=['r1 = Category1', 'r2 = Category1', 'r3 = Category1']) self.runCmd("type category delete Category1") self.runCmd("type category delete Category2") self.expect("frame variable r1 r2 r3", substrs=['r1 = {', 'r2 = {', 'r3 = {']) # Check that multiple summaries can go into one category self.runCmd( "type summary add -w Category1 --summary-string \"Width = ${var.w}, Height = ${var.h}\" Rectangle" ) self.runCmd( "type summary add -w Category1 --summary-string \"Radius = ${var.r}\" Circle" ) self.runCmd("type category enable Category1") self.expect( "frame variable r1 r2 r3", substrs=['r1 = Width = ', 'r2 = Width = ', 'r3 = Width = ']) self.expect( "frame variable c1 c2 c3", substrs=['c1 = Radius = ', 'c2 = Radius = ', 'c3 = Radius = ']) self.runCmd("type summary delete Circle -w Category1") self.expect("frame variable c1 c2 c3", substrs=['c1 = {', 'c2 = {', 'c3 = {']) # Add a regex based summary to a category self.runCmd( "type summary add -w Category1 --summary-string \"Radius = ${var.r}\" -x Circle" ) self.expect( "frame variable r1 r2 r3", substrs=['r1 = Width = ', 'r2 = Width = ', 'r3 = Width = ']) self.expect( "frame variable c1 c2 c3", substrs=['c1 = Radius = ', 'c2 = Radius = ', 'c3 = Radius = ']) # Delete it self.runCmd("type summary delete Circle -w Category1") self.expect("frame variable c1 c2 c3", substrs=['c1 = {', 'c2 = {', 'c3 = {']) # Change a summary inside a category and check that the change is # reflected self.runCmd( "type summary add Circle -w Category1 --summary-string \"summary1\"" ) self.expect( "frame variable c1 c2 c3", substrs=['c1 = summary1', 'c2 = summary1', 'c3 = summary1']) self.runCmd( "type summary add Circle -w Category1 --summary-string \"summary2\"" ) self.expect( "frame variable c1 c2 c3", substrs=['c1 = summary2', 'c2 = summary2', 'c3 = summary2']) # Check that our order of priority works. Start by clearing categories self.runCmd("type category delete Category1") self.runCmd( "type summary add Shape -w BaseCategory --summary-string \"AShape\"" ) self.runCmd("type category enable BaseCategory") self.expect("print (Shape*)&c1", substrs=['AShape']) self.expect("print (Shape*)&r1", substrs=['AShape']) self.expect("print (Shape*)c_ptr", substrs=['AShape']) self.expect("print (Shape*)r_ptr", substrs=['AShape']) self.runCmd( "type summary add Circle -w CircleCategory --summary-string \"ACircle\"" ) self.runCmd( "type summary add Rectangle -w RectangleCategory --summary-string \"ARectangle\"" ) self.runCmd("type category enable CircleCategory") self.expect("frame variable c1", substrs=['ACircle']) self.expect("frame variable c_ptr", substrs=['ACircle']) self.runCmd( "type summary add \"Rectangle *\" -w RectangleStarCategory --summary-string \"ARectangleStar\"" ) self.runCmd("type category enable RectangleStarCategory") self.expect("frame variable c1 r1 c_ptr r_ptr", substrs=['ACircle', 'ARectangleStar']) self.runCmd("type category enable RectangleCategory") self.expect("frame variable c1 r1 c_ptr r_ptr", substrs=['ACircle', 'ACircle', 'ARectangle']) # Check that abruptly deleting an enabled category does not crash us self.runCmd("type category delete RectangleCategory") self.expect("frame variable c1 r1 c_ptr r_ptr", substrs=[ 'ACircle', '(Rectangle) r1 = ', 'w = 5', 'h = 6', 'ACircle', 'ARectangleStar' ]) # check that list commands work self.expect("type category list", substrs=['RectangleStarCategory (enabled)']) self.expect("type summary list", substrs=['ARectangleStar']) # Disable a category and check that it fallsback self.runCmd("type category disable CircleCategory") # check that list commands work self.expect("type category list", substrs=['CircleCategory (disabled']) self.expect("frame variable c1 r_ptr", substrs=['AShape', 'ARectangleStar']) # check that filters work into categories self.runCmd( "type filter add Rectangle --child w --category RectangleCategory") self.runCmd("type category enable RectangleCategory") self.runCmd( "type summary add Rectangle --category RectangleCategory --summary-string \" \" -e" ) self.expect('frame variable r2', substrs=['w = 9']) self.runCmd("type summary add Rectangle --summary-string \" \" -e") self.expect('frame variable r2', matching=False, substrs=['h = 16']) # Now delete all categories self.runCmd( "type category delete CircleCategory RectangleStarCategory BaseCategory RectangleCategory" ) # check that a deleted category with filter does not blow us up self.expect('frame variable r2', substrs=['w = 9', 'h = 16']) # and also validate that one can print formatters for a language self.expect('type summary list -l c++', substrs=['vector', 'map', 'list', 'string'])
def plain_data_formatter_commands(self): """Test basic ObjC formatting behavior.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line (self, "main.m", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type synth clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.runCmd("type summary add --summary-string \"${var%@}\" MyClass") self.expect("frame variable object2", substrs = ['MyOtherClass']); self.expect("frame variable *object2", substrs = ['MyOtherClass']); # Now let's delete the 'MyClass' custom summary. self.runCmd("type summary delete MyClass") # The type format list should not show 'MyClass' at this point. self.expect("type summary list", matching=False, substrs = ['MyClass']) self.runCmd("type summary add --summary-string \"a test\" MyClass") self.expect("frame variable *object2", substrs = ['*object2 =', 'MyClass = a test', 'backup = ']); self.expect("frame variable object2", matching=False, substrs = ['a test']); self.expect("frame variable object", substrs = ['a test']); self.expect("frame variable *object", substrs = ['a test']); self.expect('frame variable myclass', substrs = ['(Class) myclass = NSValue']) self.expect('frame variable myclass2', substrs = ['(Class) myclass2 = ','NS','String']) self.expect('frame variable myclass3', substrs = ['(Class) myclass3 = Molecule']) self.expect('frame variable myclass4', substrs = ['(Class) myclass4 = NSMutableArray']) self.expect('frame variable myclass5', substrs = ['(Class) myclass5 = nil'])
def test_expr(self): 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.m", 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 --object-description -- immutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["foo"]) self.expect("expr --object-description -- mutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["foo"]) self.expect("expr --object-description -- mutable_array[0] = @\"bar\"", VARIABLES_DISPLAYED_CORRECTLY, substrs=["bar"]) self.expect("expr --object-description -- mutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["bar"]) self.expect( "expr --object-description -- immutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["value"]) self.expect( "expr --object-description -- mutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["value"]) self.expect( "expr --object-description -- mutable_dictionary[@\"key\"] = @\"object\"", VARIABLES_DISPLAYED_CORRECTLY, substrs=["object"]) self.expect( "expr --object-description -- mutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["object"]) self.expect("expr --object-description -- @[ @\"foo\", @\"bar\" ]", VARIABLES_DISPLAYED_CORRECTLY, substrs=["NSArray", "foo", "bar"]) self.expect("expr --object-description -- @{ @\"key\" : @\"object\" }", VARIABLES_DISPLAYED_CORRECTLY, substrs=["key", "object"]) self.expect("expr --object-description -- @'a'", VARIABLES_DISPLAYED_CORRECTLY, substrs=[str(ord('a'))]) self.expect("expr --object-description -- @1", VARIABLES_DISPLAYED_CORRECTLY, substrs=["1"]) self.expect("expr --object-description -- @1l", VARIABLES_DISPLAYED_CORRECTLY, substrs=["1"]) self.expect("expr --object-description -- @1ul", VARIABLES_DISPLAYED_CORRECTLY, substrs=["1"]) self.expect("expr --object-description -- @1ll", VARIABLES_DISPLAYED_CORRECTLY, substrs=["1"]) self.expect("expr --object-description -- @1ull", VARIABLES_DISPLAYED_CORRECTLY, substrs=["1"]) self.expect("expr -- @123.45", VARIABLES_DISPLAYED_CORRECTLY, substrs=["NSNumber", "123.45"]) self.expect("expr --object-description -- @( 1 + 3 )", VARIABLES_DISPLAYED_CORRECTLY, substrs=["4"]) self.expect("expr -- @((char*)\"Hello world\" + 6)", VARIABLES_DISPLAYED_CORRECTLY, substrs=["NSString", "world"])
def test_watchpoint_command(self): """Test 'watchpoint command'.""" self.build(dictionary=self.d) self.setTearDownCleanup(dictionary=self.d) exe = os.path.join(os.getcwd(), self.exe_name) self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add a breakpoint to set a watchpoint when stopped on the breakpoint. lldbutil.run_break_set_by_file_and_line( self, None, self.line, num_expected_locations=1) # self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED, # startstr = "Breakpoint created: 1: file ='%s', line = %d, locations = 1" % # (self.source, self.line))# # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # Now let's set a write-type watchpoint for 'global'. self.expect( "watchpoint set variable -w write global", WATCHPOINT_CREATED, substrs=[ 'Watchpoint created', 'size = 4', 'type = w', '%s:%d' % (self.source, self.decl)]) self.runCmd( 'watchpoint command add -s python 1 -o \'frame.EvaluateExpression("cookie = 777")\'') # List the watchpoint command we just added. self.expect("watchpoint command list 1", substrs=['frame.EvaluateExpression', 'cookie = 777']) # Use the '-v' option to do verbose listing of the watchpoint. # The hit count should be 0 initially. self.expect("watchpoint list -v", substrs=['hit_count = 0']) self.runCmd("process continue") # We should be stopped again due to the watchpoint (write type). # The stop reason of the thread should be watchpoint. self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT, substrs=['stop reason = watchpoint']) # Check that the watchpoint snapshoting mechanism is working. self.expect("watchpoint list -v", substrs=['old value:', ' = 0', 'new value:', ' = 1']) # The watchpoint command "forced" our global variable 'cookie' to # become 777. self.expect("frame variable --show-globals cookie", substrs=['(int32_t)', 'cookie = 777'])
def do_target_command(self): """Exercise 'target create', 'target list', 'target select' commands.""" exe_a = self.getBuildArtifact("a.out") exe_b = self.getBuildArtifact("b.out") exe_c = self.getBuildArtifact("c.out") self.runCmd("target list") output = self.res.GetOutput() if output.startswith("No targets"): # We start from index 0. base = 0 else: # Find the largest index of the existing list. import re pattern = re.compile("target #(\d+):") for line in reversed(output.split(os.linesep)): match = pattern.search(line) if match: # We will start from (index + 1) .... base = int(match.group(1), 10) + 1 self.trace("base is:", base) break self.runCmd("target create " + exe_a, CURRENT_EXECUTABLE_SET) self.runCmd("run", RUN_SUCCEEDED) self.runCmd("target create " + exe_b, CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, 'b.c', self.line_b, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) self.runCmd("target create " + exe_c, CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, 'c.c', self.line_c, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) self.runCmd("target list") self.runCmd("target select %d" % base) self.runCmd("thread backtrace") self.runCmd("target select %d" % (base + 2)) self.expect( "thread backtrace", STOPPED_DUE_TO_BREAKPOINT, substrs=['stop reason = breakpoint', 'c.c:%d' % self.line_c]) self.runCmd("target select %d" % (base + 1)) self.expect( "thread backtrace", STOPPED_DUE_TO_BREAKPOINT, substrs=['stop reason = breakpoint', 'b.c:%d' % self.line_b]) self.runCmd("target list")
def test_memory_read(self): """Test the 'memory read' command with plain and vector formats.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break in main() after the variables are assigned values. lldbutil.run_break_set_by_file_and_line(self, "main.cpp", 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']) # Test the memory read commands. # (lldb) memory read -f d -c 1 `&argc` # 0x7fff5fbff9a0: 1 self.runCmd("memory read -f d -c 1 `&argc`") # Find the starting address for variable 'argc' to verify later that the # '--format uint32_t[] --size 4 --count 4' option increments the address # correctly. line = self.res.GetOutput().splitlines()[0] items = line.split(':') address = int(items[0], 0) argc = int(items[1], 0) self.assertGreater(address, 0) self.assertEquals(argc, 1) # (lldb) memory read --format uint32_t[] --size 4 --count 4 `&argc` # 0x7fff5fbff9a0: {0x00000001} # 0x7fff5fbff9a4: {0x00000000} # 0x7fff5fbff9a8: {0x0ec0bf27} # 0x7fff5fbff9ac: {0x215db505} self.runCmd( "memory read --format uint32_t[] --size 4 --count 4 `&argc`") lines = self.res.GetOutput().splitlines() for i in range(4): if i == 0: # Verify that the printout for argc is correct. self.assertTrue( argc == int(lines[i].split(':')[1].strip(' {}'), 0)) addr = int(lines[i].split(':')[0], 0) # Verify that the printout for addr is incremented correctly. self.assertEquals(addr, (address + i * 4)) # (lldb) memory read --format char[] --size 7 --count 1 `&my_string` # 0x7fff5fbff990: {abcdefg} self.expect( "memory read --format char[] --size 7 --count 1 `&my_string`", substrs=['abcdefg']) # (lldb) memory read --format 'hex float' --size 16 `&argc` # 0x7fff5fbff5b0: error: unsupported byte size (16) for hex float # format self.expect( "memory read --format 'hex float' --size 16 `&argc`", substrs=['unsupported byte size (16) for hex float format']) self.expect( "memory read --format 'float' --count 1 --size 8 `&my_double`", substrs=['1234.']) # (lldb) memory read --format 'float' --count 1 --size 20 `&my_double` # 0x7fff5fbff598: error: unsupported byte size (20) for float format self.expect( "memory read --format 'float' --count 1 --size 20 `&my_double`", substrs=['unsupported byte size (20) for float format']) self.expect('memory read --type int --count 5 `&my_ints[0]`', substrs=['(int) 0x', '2', '4', '6', '8', '10']) self.expect( 'memory read --type int --count 5 --format hex `&my_ints[0]`', substrs=['(int) 0x', '0x', '0a']) self.expect( 'memory read --type int --count 5 --offset 5 `&my_ints[0]`', substrs=['(int) 0x', '12', '14', '16', '18', '20']) # the gdb format specifier and the size in characters for # the returned values including the 0x prefix. variations = [['b', 4], ['h', 6], ['w', 10], ['g', 18]] for v in variations: formatter = v[0] expected_object_length = v[1] self.runCmd("memory read --gdb-format 4%s &my_uint64s" % formatter) lines = self.res.GetOutput().splitlines() objects_read = [] for l in lines: objects_read.extend(l.split(':')[1].split()) # Check that we got back 4 0x0000 etc bytes for o in objects_read: self.assertTrue(len(o) == expected_object_length) self.assertEquals(len(objects_read), 4)
def break_multi_thread(self, removal_type, check_hw_bp=True): """Test that lldb hardware breakpoints work for multiple threads.""" self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) # Stop in main before creating any threads. lldbutil.run_break_set_by_file_and_line(self, None, self.first_stop, num_expected_locations=1) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to the breakpoint. # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # Now set a hardware breakpoint in thread function. self.expect( "breakpoint set -b hw_break_function --hardware", substrs=['Breakpoint', 'hw_break_function', 'address = 0x']) # We should stop in hw_break_function function for 4 threads. count = 0 while count < 2: self.runCmd("process continue") # We should be stopped in hw_break_function # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=[ 'hw_break_function', 'stop reason = breakpoint', ]) # Continue the loop and test that we are stopped 4 times. count += 1 if check_hw_bp: # Check the breakpoint list. self.expect("breakpoint list", substrs=['hw_break_function', 'hardware']) self.expect( "breakpoint list -v", substrs=['function = hw_break_function', 'hardware = true']) if removal_type == 'delete': self.runCmd("settings set auto-confirm true") # Now 'breakpoint delete' should just work fine without confirmation # prompt from the command interpreter. self.expect("breakpoint delete", startstr="All breakpoints removed") # Restore the original setting of auto-confirm. self.runCmd("settings clear auto-confirm") elif removal_type == 'disable': self.expect("breakpoint disable", startstr="All breakpoints disabled.") # Continue. Program should exit without stopping anywhere. self.runCmd("process continue") # Process should have stopped and exited with status = 0 self.expect("process status", PROCESS_STOPPED, patterns=['Process .* exited with status = 0'])
def breakpoint_command_sequence(self): """Test a sequence of breakpoint command add, list, and delete.""" exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Add three breakpoints on the same line. The first time we don't specify the file, # since the default file is the one containing main: lldbutil.run_break_set_by_file_and_line(self, None, self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "main.c", self.line, num_expected_locations=1, loc_exact=True) lldbutil.run_break_set_by_file_and_line(self, "main.c", self.line, num_expected_locations=1, loc_exact=True) # Breakpoint 4 - set at the same location as breakpoint 1 to test # setting breakpoint commands on two breakpoints at a time lldbutil.run_break_set_by_file_and_line(self, None, self.line, num_expected_locations=1, loc_exact=True) # Now add callbacks for the breakpoints just created. self.runCmd( "breakpoint command add -s command -o 'frame variable --show-types --scope' 1 4" ) self.runCmd( "breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); here.write(\"lldb\\n\"); here.close()' 2" ) self.runCmd( "breakpoint command add --python-function bktptcmd.function 3") # Check that the breakpoint commands are correctly set. # The breakpoint list now only contains breakpoint 1. self.expect( "breakpoint list", "Breakpoints 1 & 2 created", substrs=[ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line ], patterns=[ "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line ]) self.expect( "breakpoint list -f", "Breakpoints 1 & 2 created", substrs=[ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line ], patterns=[ "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1" % self.line, "1.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line, "2.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line ]) self.expect("breakpoint command list 1", "Breakpoint 1 command ok", substrs=[ "Breakpoint commands:", "frame variable --show-types --scope" ]) self.expect("breakpoint command list 2", "Breakpoint 2 command ok", substrs=[ "Breakpoint commands (Python):", "here = open", "here.write", "here.close()" ]) self.expect("breakpoint command list 3", "Breakpoint 3 command ok", substrs=[ "Breakpoint commands (Python):", "bktptcmd.function(frame, bp_loc, internal_dict)" ]) self.expect("breakpoint command list 4", "Breakpoint 4 command ok", substrs=[ "Breakpoint commands:", "frame variable --show-types --scope" ]) self.runCmd("breakpoint delete 4") self.runCmd("command script import --allow-reload ./bktptcmd.py") # Next lets try some other breakpoint kinds. First break with a regular expression # and then specify only one file. The first time we should get two locations, # the second time only one: lldbutil.run_break_set_by_regexp(self, r"._MyFunction", num_expected_locations=2) lldbutil.run_break_set_by_regexp(self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1) lldbutil.run_break_set_by_regexp(self, r"._MyFunction", extra_options="-f a.c -f b.c", num_expected_locations=2) # Now try a source regex breakpoint: lldbutil.run_break_set_by_source_regexp(self, r"is about to return [12]0", extra_options="-f a.c -f b.c", num_expected_locations=2) lldbutil.run_break_set_by_source_regexp(self, r"is about to return [12]0", extra_options="-f a.c", num_expected_locations=1) # Run the program. Remove 'output.txt' if it exists. self.RemoveTempFile("output.txt") self.RemoveTempFile("output2.txt") self.runCmd("run", RUN_SUCCEEDED) # Check that the file 'output.txt' exists and contains the string # "lldb". # The 'output.txt' file should now exist. self.assertTrue( os.path.isfile("output.txt"), "'output.txt' exists due to breakpoint command for breakpoint 2.") self.assertTrue( os.path.isfile("output2.txt"), "'output2.txt' exists due to breakpoint command for breakpoint 3.") # Read the output file produced by running the program. with open('output.txt', 'r') as f: output = f.read() self.expect(output, "File 'output.txt' and the content matches", exe=False, startstr="lldb") with open('output2.txt', 'r') as f: output = f.read() self.expect(output, "File 'output2.txt' and the content matches", exe=False, startstr="lldb") # Finish the program. self.runCmd("process continue") # Remove the breakpoint command associated with breakpoint 1. self.runCmd("breakpoint command delete 1") # Remove breakpoint 2. self.runCmd("breakpoint delete 2") self.expect( "breakpoint command list 1", startstr="Breakpoint 1 does not have an associated command.") self.expect( "breakpoint command list 2", error=True, startstr="error: '2' is not a currently valid breakpoint ID.") # The breakpoint list now only contains breakpoint 1. self.expect( "breakpoint list -f", "Breakpoint 1 exists", patterns=[ "1: file = '.*main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" % self.line, "hit count = 1" ]) # Not breakpoint 2. self.expect( "breakpoint list -f", "No more breakpoint 2", matching=False, substrs=[ "2: file = 'main.c', line = %d, exact_match = 0, locations = 1, resolved = 1" % self.line ]) # Run the program again, with breakpoint 1 remaining. self.runCmd("run", RUN_SUCCEEDED) # We should be stopped again due to breakpoint 1. # 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 2. self.expect("breakpoint list -f", BREAKPOINT_HIT_TWICE, substrs=['resolved, hit count = 2'])
def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line( self, "main.cpp", 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # Set the script here to ease the formatting script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');' self.runCmd( "type summary add i_am_cool --python-script \"%s\"" % script) self.expect('type summary list i_am_cool', substrs=[script]) self.expect("frame variable one", substrs=['Hello from Python', '1 time!']) self.expect("frame variable two", substrs=['Hello from Python', '4 times!']) self.runCmd("n") # skip ahead to make values change self.expect("frame variable three", substrs=['Hello from Python, 10 times!', 'Hello from Python, 4 times!']) self.runCmd("n") # skip ahead to make values change self.expect("frame variable two", substrs=['Hello from Python', '1 time!']) script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'int says \' + a_val; return str;' # Check that changes in the script are immediately reflected self.runCmd( "type summary add i_am_cool --python-script \"%s\"" % script) self.expect("frame variable two", substrs=['int says 1']) self.expect("frame variable twoptr", substrs=['int says 1']) # Change the summary self.runCmd( "type summary add --summary-string \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool") self.expect("frame variable two", substrs=['int says 1', 'and float says 2.71']) # Try it for pointers self.expect("frame variable twoptr", substrs=['int says 1', 'and float says 2.71']) # Force a failure for pointers self.runCmd( "type summary add i_am_cool -p --python-script \"%s\"" % script) self.expect("frame variable twoptr", matching=False, substrs=['and float says 2.71']) script = 'return \'Python summary\'' self.runCmd( "type summary add --name test_summary --python-script \"%s\"" % script) # attach the Python named summary to someone self.expect("frame variable one --summary test_summary", substrs=['Python summary']) # should not bind to the type self.expect("frame variable two", matching=False, substrs=['Python summary']) # and should not stick to the variable self.expect("frame variable one", matching=False, substrs=['Python summary']) self.runCmd( "type summary add i_am_cool --summary-string \"Text summary\"") # should be temporary only self.expect("frame variable one", matching=False, substrs=['Python summary']) # use the type summary self.expect("frame variable two", substrs=['Text summary']) self.runCmd("n") # skip ahead to make values change # both should use the type summary now self.expect("frame variable one", substrs=['Text summary']) self.expect("frame variable two", substrs=['Text summary']) # disable type summary for pointers, and make a Python regex summary self.runCmd( "type summary add i_am_cool -p --summary-string \"Text summary\"") self.runCmd("type summary add -x cool --python-script \"%s\"" % script) # variables should stick to the type summary self.expect("frame variable one", substrs=['Text summary']) self.expect("frame variable two", substrs=['Text summary']) # array and pointer should match the Python one self.expect("frame variable twoptr", substrs=['Python summary']) self.expect("frame variable array", substrs=['Python summary']) # return pointers to the type summary self.runCmd( "type summary add i_am_cool --summary-string \"Text summary\"") self.expect("frame variable one", substrs=['Text summary']) self.expect("frame variable two", substrs=['Text summary']) self.expect("frame variable twoptr", substrs=['Text summary']) self.expect("frame variable array", substrs=['Python summary'])
def test(self): """Test thread exit handling.""" self.build(dictionary=self.getBuildFlags()) exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # This should create a breakpoint with 1 location. bp1_id = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_1, num_expected_locations=1) bp2_id = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_2, num_expected_locations=1) bp3_id = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_3, num_expected_locations=1) bp4_id = lldbutil.run_break_set_by_file_and_line( self, "main.cpp", self.break_4, num_expected_locations=1) # The breakpoint list should show 1 locations. self.expect( "breakpoint list -f", "Breakpoint location shown correctly", substrs=[ "1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_1, "2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_2, "3: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_3, "4: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.break_4]) # Run the program. self.runCmd("run", RUN_SUCCEEDED) # Get the target process target = self.dbg.GetSelectedTarget() process = target.GetProcess() stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( process, bp1_id) self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 1") # Get the number of threads num_threads = process.GetNumThreads() self.assertGreaterEqual( num_threads, 2, 'Number of expected threads and actual threads do not match at breakpoint 1.') # Run to the second breakpoint self.runCmd("continue") stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( process, bp2_id) self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 2") # Update the number of threads new_num_threads = process.GetNumThreads() self.assertEqual( new_num_threads, num_threads + 1, 'Number of expected threads did not increase by 1 at bp 2.') # Run to the third breakpoint self.runCmd("continue") stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( process, bp3_id) self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 3") # Update the number of threads new_num_threads = process.GetNumThreads() self.assertEqual( new_num_threads, num_threads, 'Number of expected threads is not equal to original number of threads at bp 3.') # Run to the fourth breakpoint self.runCmd("continue") stopped_thread = lldbutil.get_one_thread_stopped_at_breakpoint_id( process, bp4_id) self.assertIsNotNone(stopped_thread, "Process is not stopped at breakpoint 4") # Update the number of threads new_num_threads = process.GetNumThreads() self.assertEqual( new_num_threads, num_threads - 1, 'Number of expected threads did not decrease by 1 at bp 4.') # Run to completion self.runCmd("continue") # At this point, the inferior process should have exited. self.assertEqual(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
def rdar10960550_formatter_commands(self): """Test that synthetic children persist stoppoints.""" self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) # The second breakpoint is on a multi-line expression, so the comment # can't be on the right line... lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line2, num_expected_locations=1, loc_exact=False) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line3, 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']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.runCmd("command script import ./ftsp.py --allow-reload") self.runCmd("type synth add -l ftsp.ftsp wrapint") # we need to check that the VO is properly updated so that the same synthetic children are reused # but their values change correctly across stop-points - in order to do this, self.runCmd("next") # does not work because it forces a wipe of the stack frame - this is why we are using this more contrived # mechanism to achieve our goal of preserving test_cast as a VO test_cast = self.dbg.GetSelectedTarget().GetProcess( ).GetSelectedThread().GetSelectedFrame().FindVariable('test_cast') str_cast = str(test_cast) if self.TraceOn(): print(str_cast) self.assertTrue(str_cast.find('A') != -1, 'could not find A in output') self.assertTrue(str_cast.find('B') != -1, 'could not find B in output') self.assertTrue(str_cast.find('C') != -1, 'could not find C in output') self.assertTrue(str_cast.find('D') != -1, 'could not find D in output') self.assertTrue( str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0') self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver( ) str_cast = str(test_cast) if self.TraceOn(): print(str_cast) # we detect that all the values of the child objects have changed - but the counter-generated item # is still fixed at 0 because it is cached - this would fail if update(self): in ftsp returned False # or if synthetic children were not being preserved self.assertTrue(str_cast.find('Q') != -1, 'could not find Q in output') self.assertTrue(str_cast.find('X') != -1, 'could not find X in output') self.assertTrue(str_cast.find('T') != -1, 'could not find T in output') self.assertTrue(str_cast.find('F') != -1, 'could not find F in output') self.assertTrue( str_cast.find("4 = '\\0'") != -1, 'could not find item 4 == 0')
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'])
def test_nested_alias(self): """Test that an alias can reference other aliases without crashing.""" self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) # Break in main() after the variables are assigned values. lldbutil.run_break_set_by_file_and_line(self, "main.cpp", 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. lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1) # This is the function to remove the custom aliases in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('command unalias read', check=False) self.runCmd('command unalias rd', check=False) self.runCmd('command unalias fo', check=False) self.runCmd('command unalias foself', check=False) self.runCmd('command unalias add_two', check=False) self.runCmd('command unalias two', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) self.runCmd('command alias read memory read -f A') self.runCmd('command alias rd read -c 3') self.expect('memory read -f A -c 3 `&my_ptr[0]`', substrs=['deadbeef', 'main.cpp:', 'feedbeef']) self.expect('rd `&my_ptr[0]`', substrs=['deadbeef', 'main.cpp:', 'feedbeef']) self.expect('memory read -f A -c 3 `&my_ptr[0]`', substrs=['deadfeed'], matching=False) self.expect('rd `&my_ptr[0]`', substrs=['deadfeed'], matching=False) self.runCmd('command alias fo frame variable -O --') self.runCmd('command alias foself fo self') self.expect('help foself', substrs=['--show-all-children', '--raw-output'], matching=False) self.expect('help foself', substrs=['Show variables for the current', 'stack frame.'], matching=True) # Check that foself was resolved and is now independent of 'fo'. self.runCmd('command unalias fo') self.expect('help foself', substrs=['Show variables for the current', 'stack frame.'], matching=True) # Check that aliases can be created for raw input commands. self.expect('command alias two expr -- 2') self.expect('command alias add_two two +') self.expect('add_two 3', patterns=[' = 5$'])
def data_formatter_commands(self): """Test using Python synthetic children provider.""" self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) self.runCmd("run", RUN_SUCCEEDED) process = self.dbg.GetSelectedTarget().GetProcess() # The stop reason of the thread should be breakpoint. self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) # This is the function to remove the custom formats in order to have a # clean slate for the next test case. def cleanup(): self.runCmd('type format clear', check=False) self.runCmd('type summary clear', check=False) self.runCmd('type filter clear', check=False) self.runCmd('type synth clear', check=False) # Execute the cleanup function during test case tear down. self.addTearDownHook(cleanup) # print the f00_1 variable without a synth self.expect("frame variable f00_1", substrs=['a = 1', 'b = 2', 'r = 34']) # now set up the synth self.runCmd("script from fooSynthProvider import *") self.runCmd("type synth add -l fooSynthProvider foo") self.expect("type synthetic list foo", substrs=['fooSynthProvider']) # note that the value of fake_a depends on target byte order if process.GetByteOrder() == lldb.eByteOrderLittle: fake_a_val = 0x02000000 else: fake_a_val = 0x00000100 # check that we get the two real vars and the fake_a variables self.expect("frame variable f00_1", substrs=['r = 34', 'fake_a = %d' % fake_a_val, 'a = 1']) # check that we do not get the extra vars self.expect("frame variable f00_1", matching=False, substrs=['b = 2']) # check access to members by name self.expect('frame variable f00_1.fake_a', substrs=['%d' % fake_a_val]) # check access to members by index self.expect('frame variable f00_1[1]', substrs=['%d' % fake_a_val]) # put synthetic children in summary in several combinations self.runCmd( "type summary add --summary-string \"fake_a=${svar.fake_a}\" foo") self.expect('frame variable f00_1', substrs=['fake_a=%d' % fake_a_val]) self.runCmd( "type summary add --summary-string \"fake_a=${svar[1]}\" foo") self.expect('frame variable f00_1', substrs=['fake_a=%d' % fake_a_val]) # clear the summary self.runCmd("type summary delete foo") # check that the caching does not span beyond the stopoint self.runCmd("n") if process.GetByteOrder() == lldb.eByteOrderLittle: fake_a_val = 0x02000000 else: fake_a_val = 0x00000200 self.expect("frame variable f00_1", substrs=['r = 34', 'fake_a = %d' % fake_a_val, 'a = 2']) # check that altering the object also alters fake_a self.runCmd("expr f00_1.a = 280") if process.GetByteOrder() == lldb.eByteOrderLittle: fake_a_val = 0x02000001 else: fake_a_val = 0x00011800 self.expect("frame variable f00_1", substrs=['r = 34', 'fake_a = %d' % fake_a_val, 'a = 280']) # check that expanding a pointer does the right thing if process.GetByteOrder() == lldb.eByteOrderLittle: fake_a_val = 0x0d000000 else: fake_a_val = 0x00000c00 self.expect("frame variable --ptr-depth 1 f00_ptr", substrs=['r = 45', 'fake_a = %d' % fake_a_val, 'a = 12']) # now add a filter.. it should fail self.expect("type filter add foo --child b --child j", error=True, substrs=['cannot add']) # we get the synth again.. self.expect('frame variable f00_1', matching=False, substrs=['b = 1', 'j = 17']) self.expect("frame variable --ptr-depth 1 f00_ptr", substrs=['r = 45', 'fake_a = %d' % fake_a_val, 'a = 12']) # now delete the synth and add the filter self.runCmd("type synth delete foo") self.runCmd("type filter add foo --child b --child j") self.expect('frame variable f00_1', substrs=['b = 2', 'j = 18']) self.expect("frame variable --ptr-depth 1 f00_ptr", matching=False, substrs=['r = 45', 'fake_a = %d' % fake_a_val, 'a = 12']) # now add the synth and it should fail self.expect("type synth add -l fooSynthProvider foo", error=True, substrs=['cannot add']) # check the listing self.expect('type synth list', matching=False, substrs=['foo', 'Python class fooSynthProvider']) self.expect('type filter list', substrs=['foo', '.b', '.j']) # delete the filter, add the synth self.runCmd("type filter delete foo") self.runCmd("type synth add -l fooSynthProvider foo") self.expect('frame variable f00_1', matching=False, substrs=['b = 2', 'j = 18']) self.expect("frame variable --ptr-depth 1 f00_ptr", substrs=['r = 45', 'fake_a = %d' % fake_a_val, 'a = 12']) # check the listing self.expect('type synth list', substrs=['foo', 'Python class fooSynthProvider']) self.expect('type filter list', matching=False, substrs=['foo', '.b', '.j']) # delete the synth and check that we get good output self.runCmd("type synth delete foo") self.expect("frame variable f00_1", substrs=['a = 280', 'b = 2', 'j = 18']) self.expect("frame variable f00_1", matching=False, substrs=['fake_a = '])