def test_one_and_two_debug(self): self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self._check_debug_info_is_limited(target) lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"]) # But when other shared libraries are loaded, we should be able to see # all members. self.expect_expr("inherits_from_one.member", result_value="47") self.expect_expr("inherits_from_one.one", result_value="142") self.expect_expr("inherits_from_two.member", result_value="47") self.expect_expr("inherits_from_two.one", result_value="142") self.expect_expr("inherits_from_two.two", result_value="242") self.expect_expr("one_as_member.member", result_value="47") self.expect_expr("one_as_member.one.member", result_value="147") self.expect_expr("two_as_member.member", result_value="47") self.expect_expr("two_as_member.two.one.member", result_value="147") self.expect_expr("two_as_member.two.member", result_value="247") self.expect_expr("array_of_one[2].member", result_value="174") self.expect_expr("array_of_two[2].one[2].member", result_value="174") self.expect_expr("array_of_two[2].member", result_value="274") self.expect_expr("get_one().member", result_value="124") self.expect_expr("get_two().one().member", result_value="124") self.expect_expr("get_two().member", result_value="224") self.expect_expr("shadowed_one.member", result_value="47") self.expect_expr("shadowed_one.one", result_value="142")
def test_basic_flow(self): """Test collection, decoding, and dumping instructions""" self.build() exe = self.getBuildArtifact("a.out") lldbutil.run_to_name_breakpoint(self, "main", exe_name=exe) # We start tracing from main self.runCmd("processor-trace start all") # We check the trace after the for loop self.runCmd("b " + str(line_number('main.cpp', '// Break 1'))) self.runCmd("c") # We wait a little bit to ensure the processor has send the PT packets to # the memory time.sleep(.1) # We find the start address of the 'fun' function for a later check target = self.dbg.GetSelectedTarget() fun_start_adddress = target.FindFunctions("fun")[0].GetSymbol() \ .GetStartAddress().GetLoadAddress(target) # We print the last instructions self.expect( "processor-trace show-instr-log -c 100", patterns=[ # We expect to have seen the first instruction of 'fun' hex(fun_start_adddress), # We expect to see the exit condition of the for loop "at main.cpp:" + str(line_number('main.cpp', '// Break for loop')) ]) self.runCmd("processor-trace stop")
def do_test(self, bkpt_name, compare_value, counter_value): """Test that we resolve expression operators correctly""" lldbutil.run_to_name_breakpoint( self, bkpt_name, exe_name=self.getBuildArtifact("three"), extra_images=["fooey"]) options = lldb.SBExpressionOptions() value = self.frame().EvaluateExpression("lhs == rhs", options) self.assertSuccess(value.GetError(), "Expression in %s was successful" % bkpt_name) summary = value.GetSummary() self.assertTrue( summary == compare_value, "Expression in CompareEm has wrong value: %s (expected %s)." % (summary, compare_value)) # And make sure we got did increment the counter by the right value. value = self.frame().EvaluateExpression("Fooey.GetCounter()", options) self.assertSuccess(value.GetError(), "GetCounter expression failed") counter = value.GetValueAsUnsigned() self.assertTrue( counter == counter_value, "Counter value is wrong: %d (expected %d)" % (counter, counter_value)) # Make sure the presence of these type specific == operators doesn't interfere # with finding other unrelated == operators. value = self.frame().EvaluateExpression("1 == 2", options) self.assertSuccess(value.GetError(), "1 == 2 expression couldn't run") self.assertTrue(value.GetSummary() == "false", "1 == 2 didn't return false.")
def test_frame_recognizer_multi_symbol(self): self.build() exe = self.getBuildArtifact("a.out") # Clear internal & plugins recognizers that get initialized at launch self.runCmd("frame recognizer clear") self.runCmd("command script import " + os.path.join(self.getSourceDir(), "recognizer.py")) self.expect("frame recognizer list", substrs=['no matching results found.']) self.runCmd("frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo -n bar") self.expect("frame recognizer list", substrs=['recognizer.MyFrameRecognizer, module a.out, symbol foo, symbol bar']) target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "foo", exe_name = exe) frame = thread.GetSelectedFrame() self.expect("frame recognizer info 0", substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer']) target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "bar", exe_name = exe) frame = thread.GetSelectedFrame() self.expect("frame recognizer info 0", substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer'])
def testTargetVarExpr(self): self.build() lldbutil.run_to_name_breakpoint(self, 'main') self.expect("target variable i", substrs=['i', '42']) self.expect("target variable var", patterns=['\(incomplete \*\) var = 0[xX](0)*dead']) self.expect("target variable var[0]", error=True, substrs=["can't find global variable 'var[0]'"])
def test_decode(self): """Test that we can detect an Xcode SDK from the DW_AT_LLVM_sdk attribute.""" self.build() log = self.getBuildArtifact("types.log") self.expect("log enable lldb types -f " + log) lldbutil.run_to_name_breakpoint(self, 'main') self.expect("p 1") self.check_log(log, "MacOSX")
def test_one_debug(self): self.build(dictionary=dict(STRIP_TWO="1")) target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self._check_debug_info_is_limited(target) lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"]) # In this case we should only see the members from the second library. # Note that we cannot see inherits_from_two.one because without debug # info for "Two", we cannot determine that it in fact inherits from # "One". self.expect_expr("inherits_from_one.member", result_value="47") self.expect_expr("inherits_from_one.one", result_value="142") self.expect_expr("inherits_from_two.member", result_value="47") self.expect("expr inherits_from_two.one", error=True, substrs=["no member named 'one' in 'InheritsFromTwo'"]) self.expect("expr inherits_from_two.two", error=True, substrs=["no member named 'two' in 'InheritsFromTwo'"]) self.expect_expr("one_as_member.member", result_value="47") self.expect_expr("one_as_member.one.member", result_value="147") self.expect_expr("two_as_member.member", result_value="47") self.expect("expr two_as_member.two.one.member", error=True, substrs=["no member named 'one' in 'member::Two'"]) self.expect("expr two_as_member.two.member", error=True, substrs=["no member named 'member' in 'member::Two'"]) self.expect_expr("array_of_one[2].member", result_value="174") self.expect("expr array_of_two[2].one[2].member", error=True, substrs=["no member named 'one' in 'array::Two'"]) self.expect("expr array_of_two[2].member", error=True, substrs=["no member named 'member' in 'array::Two'"]) self.expect_expr("get_one().member", result_value="124") self.expect( "expr get_two().one().member", error=True, substrs=[ "calling 'get_two' with incomplete return type 'result::Two'" ]) self.expect( "expr get_two().member", error=True, substrs=[ "calling 'get_two' with incomplete return type 'result::Two'" ])
def test_frame_recognizer_target_specific(self): self.build() exe = self.getBuildArtifact("a.out") # Clear internal & plugins recognizers that get initialized at launch self.runCmd("frame recognizer clear") # Create a target. target, process, thread, _ = lldbutil.run_to_name_breakpoint( self, "foo", exe_name=exe) self.runCmd("command script import " + os.path.join(self.getSourceDir(), "recognizer.py")) # Check that this doesn't contain our own FrameRecognizer somehow. self.expect("frame recognizer list", matching=False, substrs=['MyFrameRecognizer']) # Add a frame recognizer in that target. self.runCmd( "frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo -n bar" ) self.expect( "frame recognizer list", substrs=[ 'recognizer.MyFrameRecognizer, module a.out, symbol foo, symbol bar' ]) self.expect( "frame recognizer info 0", substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer']) # Create a second target. That one shouldn't have the frame recognizer. target, process, thread, _ = lldbutil.run_to_name_breakpoint( self, "bar", exe_name=exe) self.expect("frame recognizer info 0", substrs=['frame 0 not recognized by any recognizer']) # Add a frame recognizer to the new target. self.runCmd( "frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n bar" ) self.expect( "frame recognizer list", substrs=['recognizer.MyFrameRecognizer, module a.out, symbol bar']) # Now the new target should also recognize the frame. self.expect( "frame recognizer info 0", substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer'])
def test_decode_sim(self): """Test that we can detect an Xcode SDK that is different from the host SDK from the DW_AT_LLVM_sdk attribute.""" arch = self.getArchitecture() self.build(dictionary={'TRIPLE': arch+'-apple-ios-simulator', 'ARCH': arch}) log = self.getBuildArtifact("types.log") self.expect("log enable lldb types -f " + log) lldbutil.run_to_name_breakpoint(self, 'main') self.expect("p 1") self.check_log(log, "iPhoneSimulator")
def test_two_debug(self): self.build(dictionary=dict(STRIP_ONE="1")) target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self._check_debug_info_is_limited(target) lldbutil.run_to_name_breakpoint(self, "main", extra_images=["one", "two"]) # This time, we should only see the members from the second library. self.expect_expr("inherits_from_one.member", result_value="47") self.expect("expr inherits_from_one.one", error=True, substrs=["no member named 'one' in 'InheritsFromOne'"]) self.expect_expr("inherits_from_two.member", result_value="47") self.expect("expr inherits_from_two.one", error=True, substrs=["no member named 'one' in 'InheritsFromTwo'"]) self.expect_expr("inherits_from_two.two", result_value="242") self.expect_expr("one_as_member.member", result_value="47") self.expect("expr one_as_member.one.member", error=True, substrs=["no member named 'member' in 'member::One'"]) self.expect_expr("two_as_member.member", result_value="47") self.expect("expr two_as_member.two.one.member", error=True, substrs=["no member named 'member' in 'member::One'"]) self.expect_expr("two_as_member.two.member", result_value="247") self.expect("expr array_of_one[2].member", error=True, substrs=["no member named 'member' in 'array::One'"]) self.expect("expr array_of_two[2].one[2].member", error=True, substrs=["no member named 'member' in 'array::One'"]) self.expect_expr("array_of_two[2].member", result_value="274") self.expect( "expr get_one().member", error=True, substrs=[ "calling 'get_one' with incomplete return type 'result::One'" ]) self.expect( "expr get_two().one().member", error=True, substrs=[ "calling 'one' with incomplete return type 'result::One'" ]) self.expect_expr("get_two().member", result_value="224")
def test_override(self): """Test that we can override the Xcode SDK using the target setting.""" self.build() log = self.getBuildArtifact("types.log") self.expect("log enable lldb types -f " + log) ios_sdk = subprocess.check_output( ['xcrun', '--show-sdk-path', '--sdk', 'iphonesimulator']).decode("utf-8").strip() self.assertGreater(len(ios_sdk), len('iphonesimulator'), "couldn't find an iOS SDK") self.expect("settings set target.sdk-path " + str(ios_sdk)) lldbutil.run_to_name_breakpoint(self, 'main') self.expect("p 1") self.check_log(log, ios_sdk)
def test_for_cpp_support(self): self.build() exe = self.getBuildArtifact("a.out") (self.target, self.process, thread, inner_sint_bkpt) = lldbutil.run_to_name_breakpoint(self, "inner_sint", exe_name=exe) error = lldb.SBError() self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) main_bktp = self.target.BreakpointCreateByName("main", exe) self.assertTrue(main_bktp, VALID_BREAKPOINT) self.process = self.target.LaunchSimple( None, None, self.get_process_working_directory()) self.assertEqual( len( lldbutil.get_threads_stopped_at_breakpoint( self.process, main_bktp)), 1) # nested struct tests self.return_and_test_struct_value("return_nested_one_float_three_base") self.return_and_test_struct_value( "return_double_nested_one_float_one_nested") self.return_and_test_struct_value("return_nested_float_struct") # class test self.return_and_test_struct_value("return_base_class_one_char") self.return_and_test_struct_value("return_nested_class_float_and_base") self.return_and_test_struct_value( "return_double_nested_class_float_and_nested") self.return_and_test_struct_value("return_base_class") self.return_and_test_struct_value("return_derived_class")
def test_allocator_self(self): """That the default runtime library path can be recovered even if paths weren't serialized.""" self.build() log = self.getBuildArtifact("types.log") command_result = lldb.SBCommandReturnObject() interpreter = self.dbg.GetCommandInterpreter() interpreter.HandleCommand("log enable lldb types -f " + log, command_result) target, process, thread, bkpt = lldbutil.run_to_name_breakpoint( self, 'main') self.expect("p 1") logfile = open(log, "r") in_expr_log = 0 found = 0 for line in logfile: if line.startswith( " SwiftASTContextForExpressions::LogConfiguration"): in_expr_log += 1 if in_expr_log and "Runtime library paths" in line and \ "2 items" in line: found += 1 self.assertEqual(in_expr_log, 1) self.assertEqual(found, 1)
def test(self): """Test SBFrame.GetLanguageSpecificData() in async functions""" self.build() # This test uses "main" as a prefix for all functions, so that all will # be stopped at. Setting a breakpoint on "main" results in a breakpoint # at the start of each coroutine "funclet" function. target, process, thread, _ = lldbutil.run_to_name_breakpoint( self, "main") # Skip the real `main`. All other stops will be Swift async functions. self.assertEqual(thread.frames[0].name, "main") process.Continue() regex_bpno = lldbutil.run_break_set_by_regexp(self, "^main[[:digit:]]") while process.state == lldb.eStateStopped: thread = process.GetSelectedThread() frame = thread.frames[0] data = frame.GetLanguageSpecificData() is_async = data.GetValueForKey( "IsSwiftAsyncFunction").GetBooleanValue() self.assertTrue(is_async) process.Continue() bkpt = target.FindBreakpointByID(regex_bpno) self.assertEqual(bkpt.GetHitCount(), bkpt.num_locations) for location in bkpt.locations: self.assertEqual(location.GetHitCount(), 1)
def test_run_healthcheck(self): """Test that an underspecified triple is upgraded with a version number. """ self.build() target, process, thread, bkpt = lldbutil.run_to_name_breakpoint( self, 'main') self.expect("p 1") result = lldb.SBCommandReturnObject() ret_val = self.dbg.GetCommandInterpreter().HandleCommand( "swift-healthcheck", result) log = result.GetOutput()[:-1].split(" ")[-1] self.assertEquals(log[-4:], ".log") import io, re logfile = io.open(log, "r", encoding='utf-8') good = 0 bad = 0 for line in logfile: if re.search('swift-healthcheck', line): good += 1 continue if re.search('Unsupported mixing"', line): bad += 1 break self.assertGreater(good, 1) self.assertEquals(bad, 0)
def set_use_source_cache_and_test(self, is_cache_enabled): """Common test for both True/False values of use-source-cache.""" self.build() # Enable/Disable source cache self.runCmd("settings set use-source-cache " + ("true" if is_cache_enabled else "false")) # Get paths for the main source file. src = self.getBuildArtifact("main-copy.cpp") self.assertTrue(src) # Make sure source file is bigger than 16K to trigger memory mapping self.assertGreater(os.stat(src).st_size, 4 * 4096) target, process, thread, breakpoint = lldbutil.run_to_name_breakpoint( self, "calc") # Show the source file contents to make sure LLDB loads src file. self.runCmd("source list") # Try deleting the source file. is_file_removed = self.removeFile(src) if is_cache_enabled: self.assertFalse( is_file_removed, "Source cache is enabled, but delete file succeeded") if not is_cache_enabled: self.assertTrue( is_file_removed, "Source cache is disabled, but delete file failed")
def test_damaged_module(self): """Test what happens when a .swiftmodule can't be loaded""" self.prepare() with open(self.getBuildArtifact("a.swiftmodule"), 'w') as mod: mod.write('I am damaged.\n') target, process, _, _ = lldbutil.run_to_name_breakpoint(self, 'main') self.run_tests(target, process)
def test_swift_deployment_target_dlopen(self): self.build() target, process, _, _, = lldbutil.run_to_name_breakpoint( self, 'main', exe_name="dlopen_module") bkpt = target.BreakpointCreateBySourceRegex( 'break here', lldb.SBFileSpec('NewerTarget.swift')) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("p self", substrs=['i = 23'])
def test_basic_flow(self): """Test collection, decoding, and dumping instructions""" if os.environ.get('TEST_INTEL_PT') != '1': self.skipTest( "The environment variable TEST_INTEL_PT=1 is needed to run this test." ) lldb_exec_dir = os.environ["LLDB_IMPLIB_DIR"] lldb_lib_dir = os.path.join(lldb_exec_dir, os.pardir, "lib") plugin_file = os.path.join(lldb_lib_dir, "liblldbIntelFeatures.so") self.build() self.runCmd("plugin load " + plugin_file) exe = self.getBuildArtifact("a.out") lldbutil.run_to_name_breakpoint(self, "main", exe_name=exe) # We start tracing from main self.runCmd("processor-trace start all") # We check the trace after the for loop self.runCmd("b " + str(line_number('main.cpp', '// Break 1'))) self.runCmd("c") # We wait a little bit to ensure the processor has send the PT packets to # the memory time.sleep(.1) # We find the start address of the 'fun' function for a later check target = self.dbg.GetSelectedTarget() fun_start_adddress = target.FindFunctions("fun")[0].GetSymbol() \ .GetStartAddress().GetLoadAddress(target) # We print the last instructions self.expect( "processor-trace show-instr-log -c 100", patterns=[ # We expect to have seen the first instruction of 'fun' hex(fun_start_adddress), # We expect to see the exit condition of the for loop "at main.cpp:" + str(line_number('main.cpp', '// Break for loop')) ]) self.runCmd("processor-trace stop")
def test(self): self.build() target, process, _, _ = lldbutil.run_to_name_breakpoint( self, 'main') self.expect("source list -n main", substrs=["Hello Absolute"]) bkpt = target.BreakpointCreateByName('relative') lldbutil.continue_to_breakpoint(process, bkpt) self.expect("source list -n relative", substrs=["Hello Relative"])
def do_test_template_function(self, add_cast): self.build() (_, _, thread, _) = lldbutil.run_to_name_breakpoint(self, "main") frame = thread.GetSelectedFrame() expr = "foo(42)" if add_cast: expr = "(int)" + expr expr_result = frame.EvaluateExpression(expr) self.assertTrue(expr_result.IsValid()) self.assertEqual(expr_result.GetValue(), "42")
def test(self): """Test that a late loaded Swift dylib with Clang dependencies is debuggable""" self.build() target, process, _, _ = lldbutil.run_to_name_breakpoint(self, "main") # Initialize SwiftASTContext before loading the dylib. self.expect("expr -l Swift -- 0") bkpt = target.BreakpointCreateByLocation( lldb.SBFileSpec('dylib.swift'), 5) lldbutil.continue_to_breakpoint(process, bkpt) self.expect("v x", substrs=['42']) self.expect("expr x", substrs=['42'])
def test(self): """Test `frame variable` in async functions""" self.build() # Setting a breakpoint on "inner" results in a breakpoint at the start # of each coroutine "funclet" function. _, process, _, _ = lldbutil.run_to_name_breakpoint(self, 'inner') # The step-over actions in the below commands may not be needed in the # future, but for now they are. This comment describes why. Take the # following line of code: # let x = await asyncFunc() # Some breakpoints, including the ones in this test, resolve to # locations that are at the start of resume functions. At the start of # the resume function, the assignment may not be complete. In order to # ensure assignment takes place, step-over is used to take execution to # the next line. stop_num = 0 while process.state == lldb.eStateStopped: thread = process.GetSelectedThread() frame = thread.frames[0] if stop_num == 0: # Start of the function. pass elif stop_num == 1: # After first await, read `a`. a = frame.FindVariable("a") self.assertTrue(a.IsValid()) self.assertEqual(a.unsigned, 0) # Step to complete `a`'s assignment (stored in the stack). thread.StepOver() self.assertGreater(a.unsigned, 0) elif stop_num == 2: # After second, read `a` and `b`. # At this point, `a` can be read from the async context. a = frame.FindVariable("a") self.assertTrue(a.IsValid()) self.assertGreater(a.unsigned, 0) b = frame.FindVariable("b") self.assertTrue(b.IsValid()) self.assertEqual(b.unsigned, 0) # Step to complete `b`'s assignment (stored in the stack). thread.StepOver() self.assertGreater(b.unsigned, 0) else: # Unexpected stop. self.assertTrue(False) stop_num += 1 process.Continue()
def test_expr(self): with open(self.getBuildArtifact("module.modulemap"), "w") as f: f.write(""" module Foo { header "f.h" } """) with open(self.getBuildArtifact("f.h"), "w") as f: f.write(""" struct Q { int i; }; void f() {} """) mod_cache = self.getBuildArtifact("private-module-cache") if os.path.isdir(mod_cache): shutil.rmtree(mod_cache) d = {'OBJC_SOURCES': 'first.m'} self.build(dictionary=d) self.assertTrue(os.path.isdir(mod_cache), "module cache exists") logfile = self.getBuildArtifact("modules.log") self.runCmd("log enable -f %s lldb module" % logfile) target, process, _, bkpt = lldbutil.run_to_name_breakpoint( self, "main") self.assertIn("int i", str(target.FindTypes('Q').GetTypeAtIndex(0))) self.expect("image list -g", patterns=[r'first\.o', r'Foo.*\.pcm']) # Update the module. with open(self.getBuildArtifact("f.h"), "w") as f: f.write(""" struct S { int i; }; struct S getS() { struct S r = {1}; return r; } void f() {} """) # Rebuild. d = {'OBJC_SOURCES': 'second.m'} self.build(dictionary=d) # Reattach. process.Kill() target, process, _, _ = lldbutil.run_to_breakpoint_do_run( self, target, bkpt) self.assertIn("int i", str(target.FindTypes('S').GetTypeAtIndex(0))) self.expect("image list -g", patterns=[r'second\.o', r'Foo.*\.pcm']) # Check log file. found = False with open(logfile, 'r') as f: for line in f: if "module changed" in line and "Foo" in line: found = True self.assertTrue(found)
def test(self): """Test that clang flags pointing into an SDK on a different machine are remapped""" self.build() log = self.getBuildArtifact("types.log") self.runCmd('log enable lldb types -f "%s"' % log) target, process, thread, bkpt = lldbutil.run_to_name_breakpoint( self, 'main') self.expect("p 1", substrs=["1"]) # Scan through the types log. logfile = open(log, "r") found = 0 for line in logfile: if line.startswith( ' SwiftASTContext("a.out")::RemapClangImporterOptions() -- remapped' ): if '/LocalSDK/' in line: found += 1 self.assertEqual(found, 1)
def test_custom_triple(self): """ Test support for serialized custom triples. Unfortunately things like the vendor name can affect Swift's ability to find the correct stdlib. """ self.build() logfile = self.getBuildArtifact('types.log') self.expect("log enable lldb types -f " + logfile) target, process, thread, bkpt = \ lldbutil.run_to_name_breakpoint(self, 'main') self.expect("p 1") log = open(logfile, 'r') n = 0 saw_aout_context = False saw_scratch_context = False expect_triple = False for line in log: if 'SwiftASTContext("a.out")::LogConfiguration' in line: expect_triple = True saw_aout_context = True continue if 'SwiftASTContextForExpressions::LogConfiguration' in line: expect_triple = True saw_scratch_context = True continue if expect_triple: self.assertTrue('Architecture' in line) self.assertTrue('x86_64-awesomevendor-linux' in line) expect_triple = False n += 1 self.assertTrue(saw_aout_context) self.assertTrue(saw_scratch_context) self.assertEquals(n, 2)
def testTargetVarExpr(self): self.build() lldbutil.run_to_name_breakpoint(self, 'main') self.expect("target variable i", substrs=['i', '42'])
def test_objc_exceptions_at_throw(self): self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) launch_info = lldb.SBLaunchInfo(["a.out", "0"]) lldbutil.run_to_name_breakpoint(self, "objc_exception_throw", launch_info=launch_info) self.expect( "thread list", substrs=['stopped', 'stop reason = hit Objective-C exception']) self.expect('thread exception', substrs=[ '(NSException *) exception = ', '"SomeReason"', ]) target = self.dbg.GetSelectedTarget() thread = target.GetProcess().GetSelectedThread() frame = thread.GetSelectedFrame() opts = lldb.SBVariablesOptions() opts.SetIncludeRecognizedArguments(True) variables = frame.GetVariables(opts) self.assertEqual(variables.GetSize(), 1) self.assertEqual(variables.GetValueAtIndex(0).name, "exception") self.assertEqual( variables.GetValueAtIndex(0).GetValueType(), lldb.eValueTypeVariableArgument) lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.mm"), launch_info=launch_info) self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) target = self.dbg.GetSelectedTarget() thread = target.GetProcess().GetSelectedThread() frame = thread.GetSelectedFrame() # No exception being currently thrown/caught at this point self.assertFalse(thread.GetCurrentException().IsValid()) self.assertFalse(thread.GetCurrentExceptionBacktrace().IsValid()) self.expect('frame variable e1', substrs=['(NSException *) e1 = ', '"SomeReason"']) self.expect('frame variable --dynamic-type no-run-target *e1', substrs=[ '(NSException) *e1 = ', 'name = ', '"ExceptionName"', 'reason = ', '"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', 'nil', ]) e1 = frame.FindVariable("e1") self.assertTrue(e1) self.assertEqual(e1.type.name, "NSException *") self.assertEqual(e1.GetSummary(), '"SomeReason"') self.assertEqual( e1.GetChildMemberWithName("name").description, "ExceptionName") self.assertEqual( e1.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e1.GetChildMemberWithName("userInfo").dynamic self.assertEqual(userInfo.summary, "1 key/value pair") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") self.assertEqual( e1.GetChildMemberWithName("reserved").description, "<nil>") self.expect('frame variable e2', substrs=['(NSException *) e2 = ', '"SomeReason"']) self.expect('frame variable --dynamic-type no-run-target *e2', substrs=[ '(NSException) *e2 = ', 'name = ', '"ThrownException"', 'reason = ', '"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', ]) e2 = frame.FindVariable("e2") self.assertTrue(e2) self.assertEqual(e2.type.name, "NSException *") self.assertEqual(e2.GetSummary(), '"SomeReason"') self.assertEqual( e2.GetChildMemberWithName("name").description, "ThrownException") self.assertEqual( e2.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e2.GetChildMemberWithName("userInfo").dynamic self.assertEqual(userInfo.summary, "1 key/value pair") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") reserved = e2.GetChildMemberWithName("reserved").dynamic self.assertGreater(reserved.num_children, 0) callStackReturnAddresses = [ reserved.GetChildAtIndex(i).GetChildAtIndex(1) for i in range(0, reserved.GetNumChildren()) if reserved.GetChildAtIndex(i).GetChildAtIndex(0).description == "callStackReturnAddresses" ][0].dynamic children = [ callStackReturnAddresses.GetChildAtIndex(i) for i in range(0, callStackReturnAddresses.num_children) ] pcs = [i.unsigned for i in children] names = [ target.ResolveSymbolContextForAddress(lldb.SBAddress( pc, target), lldb.eSymbolContextSymbol).GetSymbol().name for pc in pcs ] for n in ["objc_exception_throw", "foo(int)", "main"]: self.assertTrue( n in names, "%s is in the exception backtrace (%s)" % (n, names))
def test_with_python(self): """Test getting return values from stepping out.""" self.build() exe = self.getBuildArtifact("a.out") (self.target, self.process, thread, inner_sint_bkpt) = lldbutil.run_to_name_breakpoint(self, "inner_sint", exe_name=exe) error = lldb.SBError() # inner_sint returns the variable value, so capture that here: in_int = thread.GetFrameAtIndex(0).FindVariable( "value").GetValueAsSigned(error) self.assertSuccess(error) thread.StepOut() self.assertEquals(self.process.GetState(), lldb.eStateStopped) self.assertEquals(thread.GetStopReason(), lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertEquals(fun_name, "outer_sint(int)") return_value = thread.GetStopReturnValue() self.assertTrue(return_value.IsValid()) ret_int = return_value.GetValueAsSigned(error) self.assertSuccess(error) self.assertEquals(in_int, ret_int) # Run again and we will stop in inner_sint the second time outer_sint is called. # Then test stepping out two frames at once: thread_list = lldbutil.continue_to_breakpoint(self.process, inner_sint_bkpt) self.assertEquals(len(thread_list), 1) thread = thread_list[0] # We are done with the inner_sint breakpoint: self.target.BreakpointDelete(inner_sint_bkpt.GetID()) frame = thread.GetFrameAtIndex(1) fun_name = frame.GetFunctionName() self.assertEquals(fun_name, "outer_sint(int)") in_int = frame.FindVariable("value").GetValueAsSigned(error) self.assertSuccess(error) thread.StepOutOfFrame(frame) self.assertEquals(self.process.GetState(), lldb.eStateStopped) self.assertEquals(thread.GetStopReason(), lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertEquals(fun_name, "main") ret_value = thread.GetStopReturnValue() self.assertTrue(return_value.IsValid()) ret_int = ret_value.GetValueAsSigned(error) self.assertSuccess(error) self.assertEquals(2 * in_int, ret_int) # Now try some simple returns that have different types: inner_float_bkpt = self.target.BreakpointCreateByName( "inner_float(float)", exe) self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT) self.process.Continue() thread_list = lldbutil.get_threads_stopped_at_breakpoint( self.process, inner_float_bkpt) self.assertEquals(len(thread_list), 1) thread = thread_list[0] self.target.BreakpointDelete(inner_float_bkpt.GetID()) frame = thread.GetFrameAtIndex(0) in_value = frame.FindVariable("value") in_float = float(in_value.GetValue()) thread.StepOut() self.assertEquals(self.process.GetState(), lldb.eStateStopped) self.assertEquals(thread.GetStopReason(), lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertEquals(fun_name, "outer_float(float)") #return_value = thread.GetStopReturnValue() #self.assertTrue(return_value.IsValid()) #return_float = float(return_value.GetValue()) #self.assertEqual(in_float, return_float) if not self.affected_by_pr44132(): self.return_and_test_struct_value("return_one_int") self.return_and_test_struct_value("return_two_int") self.return_and_test_struct_value("return_three_int") self.return_and_test_struct_value("return_four_int") if not self.affected_by_pr33042(): self.return_and_test_struct_value("return_five_int") self.return_and_test_struct_value("return_two_double") self.return_and_test_struct_value("return_one_double_two_float") self.return_and_test_struct_value( "return_one_int_one_float_one_int") self.return_and_test_struct_value("return_one_pointer") self.return_and_test_struct_value("return_two_pointer") self.return_and_test_struct_value("return_one_float_one_pointer") self.return_and_test_struct_value("return_one_int_one_pointer") self.return_and_test_struct_value("return_three_short_one_float") self.return_and_test_struct_value("return_one_int_one_double") self.return_and_test_struct_value( "return_one_int_one_double_one_int") self.return_and_test_struct_value( "return_one_short_one_double_one_short") self.return_and_test_struct_value( "return_one_float_one_int_one_float") self.return_and_test_struct_value("return_two_float") # I am leaving out the packed test until we have a way to tell CLANG # about alignment when reading DWARF for packed types. #self.return_and_test_struct_value ("return_one_int_one_double_packed") self.return_and_test_struct_value("return_one_int_one_long")
def test_objc_exceptions_at_throw(self): self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) launch_info = lldb.SBLaunchInfo(["a.out", "0"]) lldbutil.run_to_name_breakpoint(self, "objc_exception_throw", launch_info=launch_info) self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) self.expect('thread exception', substrs=[ '(NSException *) exception = ', 'name: "ThrownException" - reason: "SomeReason"', ]) target = self.dbg.GetSelectedTarget() thread = target.GetProcess().GetSelectedThread() frame = thread.GetSelectedFrame() opts = lldb.SBVariablesOptions() opts.SetIncludeRecognizedArguments(True) variables = frame.GetVariables(opts) self.assertEqual(variables.GetSize(), 1) self.assertEqual(variables.GetValueAtIndex(0).name, "exception") self.assertEqual(variables.GetValueAtIndex(0).GetValueType(), lldb.eValueTypeVariableArgument) lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.mm"), launch_info=launch_info) self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) target = self.dbg.GetSelectedTarget() thread = target.GetProcess().GetSelectedThread() frame = thread.GetSelectedFrame() # No exception being currently thrown/caught at this point self.assertFalse(thread.GetCurrentException().IsValid()) self.assertFalse(thread.GetCurrentExceptionBacktrace().IsValid()) self.expect( 'frame variable e1', substrs=[ '(NSException *) e1 = ', 'name: "ExceptionName" - reason: "SomeReason"' ]) self.expect( 'frame variable --dynamic-type no-run-target *e1', substrs=[ '(NSException) *e1 = ', 'name = ', '"ExceptionName"', 'reason = ', '"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', 'nil', ]) e1 = frame.FindVariable("e1") self.assertTrue(e1) self.assertEqual(e1.type.name, "NSException *") self.assertEqual(e1.GetSummary(), 'name: "ExceptionName" - reason: "SomeReason"') self.assertEqual(e1.GetChildMemberWithName("name").description, "ExceptionName") self.assertEqual(e1.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e1.GetChildMemberWithName("userInfo").dynamic self.assertEqual(userInfo.summary, "1 key/value pair") self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") self.assertEqual(e1.GetChildMemberWithName("reserved").description, "<nil>") self.expect( 'frame variable e2', substrs=[ '(NSException *) e2 = ', 'name: "ThrownException" - reason: "SomeReason"' ]) self.expect( 'frame variable --dynamic-type no-run-target *e2', substrs=[ '(NSException) *e2 = ', 'name = ', '"ThrownException"', 'reason = ', '"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', ]) e2 = frame.FindVariable("e2") self.assertTrue(e2) self.assertEqual(e2.type.name, "NSException *") self.assertEqual(e2.GetSummary(), 'name: "ThrownException" - reason: "SomeReason"') self.assertEqual(e2.GetChildMemberWithName("name").description, "ThrownException") self.assertEqual(e2.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e2.GetChildMemberWithName("userInfo").dynamic self.assertEqual(userInfo.summary, "1 key/value pair") self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") reserved = e2.GetChildMemberWithName("reserved").dynamic self.assertGreater(reserved.num_children, 0) callStackReturnAddresses = [reserved.GetChildAtIndex(i).GetChildAtIndex(1) for i in range(0, reserved.GetNumChildren()) if reserved.GetChildAtIndex(i).GetChildAtIndex(0).description == "callStackReturnAddresses"][0].dynamic children = [callStackReturnAddresses.GetChildAtIndex(i) for i in range(0, callStackReturnAddresses.num_children)] pcs = [i.unsigned for i in children] names = [target.ResolveSymbolContextForAddress(lldb.SBAddress(pc, target), lldb.eSymbolContextSymbol).GetSymbol().name for pc in pcs] for n in ["objc_exception_throw", "foo(int)", "main"]: self.assertTrue(n in names, "%s is in the exception backtrace (%s)" % (n, names))
def test_with_python(self): """Test getting return values from stepping out.""" self.build() exe = self.getBuildArtifact("a.out") (self.target, self.process, thread, inner_sint_bkpt) = lldbutil.run_to_name_breakpoint(self, "inner_sint", exe_name = exe) error = lldb.SBError() # inner_sint returns the variable value, so capture that here: in_int = thread.GetFrameAtIndex(0).FindVariable( "value").GetValueAsSigned(error) self.assertTrue(error.Success()) thread.StepOut() self.assertTrue(self.process.GetState() == lldb.eStateStopped) self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "outer_sint") return_value = thread.GetStopReturnValue() self.assertTrue(return_value.IsValid()) ret_int = return_value.GetValueAsSigned(error) self.assertTrue(error.Success()) self.assertTrue(in_int == ret_int) # Run again and we will stop in inner_sint the second time outer_sint is called. # Then test stepping out two frames at once: thread_list = lldbutil.continue_to_breakpoint(self.process, inner_sint_bkpt) self.assertTrue(len(thread_list) == 1) thread = thread_list[0] # We are done with the inner_sint breakpoint: self.target.BreakpointDelete(inner_sint_bkpt.GetID()) frame = thread.GetFrameAtIndex(1) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "outer_sint") in_int = frame.FindVariable("value").GetValueAsSigned(error) self.assertTrue(error.Success()) thread.StepOutOfFrame(frame) self.assertTrue(self.process.GetState() == lldb.eStateStopped) self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "main") ret_value = thread.GetStopReturnValue() self.assertTrue(return_value.IsValid()) ret_int = ret_value.GetValueAsSigned(error) self.assertTrue(error.Success()) self.assertTrue(2 * in_int == ret_int) # Now try some simple returns that have different types: inner_float_bkpt = self.target.BreakpointCreateByName( "inner_float", exe) self.assertTrue(inner_float_bkpt, VALID_BREAKPOINT) self.process.Continue() thread_list = lldbutil.get_threads_stopped_at_breakpoint( self.process, inner_float_bkpt) self.assertTrue(len(thread_list) == 1) thread = thread_list[0] self.target.BreakpointDelete(inner_float_bkpt.GetID()) frame = thread.GetFrameAtIndex(0) in_value = frame.FindVariable("value") in_float = float(in_value.GetValue()) thread.StepOut() self.assertTrue(self.process.GetState() == lldb.eStateStopped) self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) frame = thread.GetFrameAtIndex(0) fun_name = frame.GetFunctionName() self.assertTrue(fun_name == "outer_float") #return_value = thread.GetStopReturnValue() #self.assertTrue(return_value.IsValid()) #return_float = float(return_value.GetValue()) #self.assertTrue(in_float == return_float) if not self.affected_by_radar_34562999(): self.return_and_test_struct_value("return_one_int") self.return_and_test_struct_value("return_two_int") self.return_and_test_struct_value("return_three_int") self.return_and_test_struct_value("return_four_int") if not self.affected_by_pr33042(): self.return_and_test_struct_value("return_five_int") self.return_and_test_struct_value("return_two_double") self.return_and_test_struct_value("return_one_double_two_float") self.return_and_test_struct_value("return_one_int_one_float_one_int") self.return_and_test_struct_value("return_one_pointer") self.return_and_test_struct_value("return_two_pointer") self.return_and_test_struct_value("return_one_float_one_pointer") self.return_and_test_struct_value("return_one_int_one_pointer") self.return_and_test_struct_value("return_three_short_one_float") self.return_and_test_struct_value("return_one_int_one_double") self.return_and_test_struct_value("return_one_int_one_double_one_int") self.return_and_test_struct_value( "return_one_short_one_double_one_short") self.return_and_test_struct_value("return_one_float_one_int_one_float") self.return_and_test_struct_value("return_two_float") # I am leaving out the packed test until we have a way to tell CLANG # about alignment when reading DWARF for packed types. #self.return_and_test_struct_value ("return_one_int_one_double_packed") self.return_and_test_struct_value("return_one_int_one_long")
def test_objc_exceptions_1(self): self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) lldbutil.run_to_name_breakpoint(self, "objc_exception_throw") self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) self.expect('thread exception', substrs=[ '(NSException *) exception = ', 'name: "ThrownException" - reason: "SomeReason"', ]) lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.m")) self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, substrs=['stopped', 'stop reason = breakpoint']) target = self.dbg.GetSelectedTarget() thread = target.GetProcess().GetSelectedThread() frame = thread.GetSelectedFrame() self.expect('frame variable e1', substrs=[ '(NSException *) e1 = ', 'name: @"ExceptionName" - reason: @"SomeReason"' ]) self.expect('frame variable --dynamic-type no-run-target *e1', substrs=[ '(NSException) *e1 = ', 'name = ', '@"ExceptionName"', 'reason = ', '@"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', 'nil', ]) e1 = frame.FindVariable("e1") self.assertTrue(e1) self.assertEqual(e1.type.name, "NSException *") self.assertEqual(e1.GetSummary(), 'name: @"ExceptionName" - reason: @"SomeReason"') self.assertEqual( e1.GetChildMemberWithName("name").description, "ExceptionName") self.assertEqual( e1.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e1.GetChildMemberWithName("userInfo").dynamic self.assertEqual(userInfo.summary, "1 key/value pair") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") self.assertEqual( e1.GetChildMemberWithName("reserved").description, "<nil>") self.expect('frame variable e2', substrs=[ '(NSException *) e2 = ', 'name: @"ThrownException" - reason: @"SomeReason"' ]) self.expect('frame variable --dynamic-type no-run-target *e2', substrs=[ '(NSException) *e2 = ', 'name = ', '@"ThrownException"', 'reason = ', '@"SomeReason"', 'userInfo = ', '1 key/value pair', 'reserved = ', ]) e2 = frame.FindVariable("e2") self.assertTrue(e2) self.assertEqual(e2.type.name, "NSException *") self.assertEqual(e2.GetSummary(), 'name: @"ThrownException" - reason: @"SomeReason"') self.assertEqual( e2.GetChildMemberWithName("name").description, "ThrownException") self.assertEqual( e2.GetChildMemberWithName("reason").description, "SomeReason") userInfo = e2.GetChildMemberWithName("userInfo").dynamic self.assertEqual(userInfo.summary, "1 key/value pair") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") self.assertEqual( userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") reserved = e2.GetChildMemberWithName("reserved").dynamic self.assertGreater(reserved.num_children, 0) callStackReturnAddresses = [ reserved.GetChildAtIndex(i).GetChildAtIndex(1) for i in range(0, reserved.GetNumChildren()) if reserved.GetChildAtIndex(i).GetChildAtIndex(0).description == "callStackReturnAddresses" ][0].dynamic children = [ callStackReturnAddresses.GetChildAtIndex(i) for i in range(0, callStackReturnAddresses.num_children) ] pcs = [i.unsigned for i in children] names = [ target.ResolveSymbolContextForAddress(lldb.SBAddress( pc, target), lldb.eSymbolContextSymbol).GetSymbol().name for pc in pcs ] for n in ["objc_exception_throw", "foo", "main"]: self.assertTrue( n in names, "%s is in the exception backtrace (%s)" % (n, names))
def test_target_symbols_sepdebug_symlink_case(self): self.build() exe = self.getBuildArtifact("dirsymlink/stripped.symlink") lldbutil.run_to_name_breakpoint(self, "main", exe_name = exe)
def test_frame_recognizer_not_only_first_instruction(self): self.build() exe = self.getBuildArtifact("a.out") # Clear internal & plugins recognizers that get initialized at launch. self.runCmd("frame recognizer clear") self.runCmd("command script import " + os.path.join(self.getSourceDir(), "recognizer.py")) self.expect("frame recognizer list", substrs=['no matching results found.']) # Create a target. target, process, thread, _ = lldbutil.run_to_name_breakpoint( self, "foo", exe_name=exe) # Move the PC one instruction further. self.runCmd("next") # Add a frame recognizer in that target. self.runCmd( "frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo -n bar" ) # It's not applied to foo(), because frame's PC is not at the first instruction of the function. self.expect("frame recognizer info 0", substrs=['frame 0 not recognized by any recognizer']) # Add a frame recognizer with --first-instruction-only=true. self.runCmd("frame recognizer clear") self.runCmd( "frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo -n bar --first-instruction-only=true" ) # It's not applied to foo(), because frame's PC is not at the first instruction of the function. self.expect("frame recognizer info 0", substrs=['frame 0 not recognized by any recognizer']) # Now add a frame recognizer with --first-instruction-only=false. self.runCmd("frame recognizer clear") self.runCmd( "frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo -n bar --first-instruction-only=false" ) # This time it should recognize the frame. self.expect( "frame recognizer info 0", substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer']) opts = lldb.SBVariablesOptions() opts.SetIncludeRecognizedArguments(True) frame = thread.GetSelectedFrame() variables = frame.GetVariables(opts) self.assertEqual(variables.GetSize(), 2) self.assertEqual(variables.GetValueAtIndex(0).name, "a") self.assertEqual(variables.GetValueAtIndex(0).signed, 42) self.assertEqual( variables.GetValueAtIndex(0).GetValueType(), lldb.eValueTypeVariableArgument) self.assertEqual(variables.GetValueAtIndex(1).name, "b") self.assertEqual(variables.GetValueAtIndex(1).signed, 56) self.assertEqual( variables.GetValueAtIndex(1).GetValueType(), lldb.eValueTypeVariableArgument)