def setup_screenshot(self, debugger): frame = self.debugger.GetSelectedTarget().GetProcess( ).GetSelectedThread().GetSelectedFrame() options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) expr = """ import UIKit extension UIWindow { public func screenshot(_ path: String) { let view = self.screen.snapshotView(afterScreenUpdates: true) UIGraphicsBeginImageContext(view.bounds.size) view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) if let image = UIGraphicsGetImageFromCurrentImageContext(), let data = image.pngData() { if let fileURL = URL(string: path) { do { try data.write(to: fileURL) print("Screenshot saved") } catch { print("Error saving screenshot:", error) } } else { print("Screengraph could not get valid file path") } } else { print("Screengraph could not take a screenshot") } UIGraphicsEndImageContext() } } """ frame.EvaluateExpression(expr, options)
def test_ir_interpreter(self): self.build_and_run() options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeC_plus_plus) set_up_expressions = ["int $i = 9", "int $j = 3", "int $k = 5"] expressions = [ "$i + $j", "$i - $j", "$i * $j", "$i / $j", "$i % $k", "$i << $j", "$i & $j", "$i | $j", "$i ^ $j" ] for expression in set_up_expressions: self.frame().EvaluateExpression(expression, options) for expression in expressions: interp_expression = expression jit_expression = "(int)getpid(); " + expression interp_result = self.frame().EvaluateExpression( interp_expression, options).GetValueAsSigned() jit_result = self.frame().EvaluateExpression( jit_expression, options).GetValueAsSigned() self.assertEqual(interp_result, jit_result, "While evaluating " + expression)
def evaluateExpressionValue(expression, printErrors=True, language=lldb.eLanguageTypeObjC_plus_plus, tryAllThreads=False): frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame() options = lldb.SBExpressionOptions() options.SetLanguage(language) # Allow evaluation that contains a @throw/@catch. # By default, ObjC @throw will cause evaluation to be aborted. At the time # of a @throw, it's not known if the exception will be handled by a @catch. # An exception that's caught, should not cause evaluation to fail. options.SetTrapExceptions(False) # Give evaluation more time. options.SetTimeoutInMicroSeconds(5000000) # 5s # Most Chisel commands are not multithreaded. options.SetTryAllThreads(tryAllThreads) value = frame.EvaluateExpression(expression, options) error = value.GetError() # Retry if the error could be resolved by first importing UIKit. if (error.type == lldb.eErrorTypeExpression and error.value == lldb.eExpressionParseError and importModule(frame, 'UIKit')): value = frame.EvaluateExpression(expression, options) error = value.GetError() if printErrors and not isSuccess(error): print error return value
def do_repl_mode_test(self): target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) self.assertTrue(target, VALID_TARGET) self.registerSharedLibrariesWithTarget(target, ['Wrapper']) if lldb.remote_platform: wd = lldb.remote_platform.GetWorkingDirectory() filename = 'libCppLib.dylib' err = lldb.remote_platform.Put( lldb.SBFileSpec(self.getBuildArtifact(filename)), lldb.SBFileSpec(os.path.join(wd, filename))) self.assertFalse(err.Fail(), 'Failed to copy ' + filename) (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) frame = thread.GetFrameAtIndex(0) options = lldb.SBExpressionOptions() options.SetREPLMode(True) val = frame.EvaluateExpression("call_cpp(); 5", options) self.assertTrue( val.GetError().Success(), "Got an error evaluating expression: %s." % (val.GetError().GetCString())) self.assertEqual(val.GetValueAsUnsigned(), 5, "The expression didn't return the correct result")
def do_test(self): hidden_dir = os.path.join(self.getBuildDir(), "hidden") hidden_dylib = os.path.join(hidden_dir, "libdylib.dylib") launch_info = lldb.SBLaunchInfo(None) launch_info.SetWorkingDirectory(self.getBuildDir()) # We have to point to the hidden directory to pick up the # version of the dylib without the weak symbols: env_expr = self.platformContext.shlib_environment_var + "=" + hidden_dir launch_info.SetEnvironmentEntries([env_expr], True) (self.target, _, thread, _) = lldbutil.run_to_source_breakpoint( self, "Set a breakpoint here", self.main_source_file, launch_info = launch_info, extra_images = [hidden_dylib]) # First we have to import the Dylib module so we get the type info # for the weak symbol. We need to add the source dir to the module # search paths, and then run @import to introduce it into the expression # context: self.dbg.HandleCommand("settings set target.clang-module-search-paths " + self.getSourceDir()) self.frame = thread.frames[0] self.assertTrue(self.frame.IsValid(), "Got a good frame") options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeObjC) result = self.frame.EvaluateExpression("@import Dylib", options) # Now run an expression that references an absent weak symbol: self.run_weak_var_check("absent_weak_int", False) self.run_weak_var_check("absent_weak_function", False) # Make sure we can do the same thing with present weak symbols self.run_weak_var_check("present_weak_int", True) self.run_weak_var_check("present_weak_function", True)
def evaluateExpressionValue(expression, printErrors=True, language=lldb.eLanguageTypeObjC_plus_plus): frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame() options = lldb.SBExpressionOptions() options.SetLanguage(language) # Allow evaluation that contains a @throw/@catch. # By default, ObjC @throw will cause evaluation to be aborted. At the time # of a @throw, it's not known if the exception will be handled by a @catch. # An exception that's caught, should not cause evaluation to fail. options.SetTrapExceptions(False) # Give evaluation more time. options.SetTimeoutInMicroSeconds(5000000) # 5s # Chisel commands are not multithreaded. options.SetTryAllThreads(False) value = frame.EvaluateExpression(expression, options) error = value.GetError() if printErrors and error.Fail(): # When evaluating a `void` expression, the returned value has an error code named kNoResult. # This is not an error that should be printed. This follows what the built in `expression` command does. # See: https://git.io/vwpjl (UserExpression.h) kNoResult = 0x1001 if error.GetError() != kNoResult: print error return value
def try_expressions(self): """Test calling expressions with errors that can be fixed by the FixIts.""" (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint( self, 'Stop here to evaluate expressions', self.main_source_spec) options = lldb.SBExpressionOptions() options.SetAutoApplyFixIts(True) frame = self.thread.GetFrameAtIndex(0) # Try with one error: value = frame.EvaluateExpression("my_pointer.first", options) self.assertTrue(value.IsValid()) self.assertTrue(value.GetError().Success()) self.assertTrue(value.GetValueAsUnsigned() == 10) # Try with two errors: two_error_expression = "my_pointer.second->a" value = frame.EvaluateExpression(two_error_expression, options) self.assertTrue(value.IsValid()) self.assertTrue(value.GetError().Success()) self.assertTrue(value.GetValueAsUnsigned() == 20) # Now turn off the fixits, and the expression should fail: options.SetAutoApplyFixIts(False) value = frame.EvaluateExpression(two_error_expression, options) self.assertTrue(value.IsValid()) self.assertTrue(value.GetError().Fail()) error_string = value.GetError().GetCString() self.assertTrue( error_string.find("fixed expression suggested:") != -1, "Fix was suggested") self.assertTrue( error_string.find("my_pointer->second.a") != -1, "Fix was right")
def do_test(self, bkpt_name, compare_value, counter_value): """Test that we resolve expression operators correctly""" exe_name = "three" exe = os.path.join(os.getcwd(), exe_name) def cleanup(): execute_command("make cleanup") self.addTearDownHook(cleanup) # Create the target target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) # Set the breakpoints bkpt = target.BreakpointCreateByName(bkpt_name) self.assertTrue(bkpt.GetNumLocations() > 0, VALID_BREAKPOINT) env_arr = self.registerSharedLibrariesWithTarget(target, ["fooey"]) process = target.LaunchSimple(None, env_arr, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.assertTrue(self.frame, "Frame 0 is valid.") options = lldb.SBExpressionOptions() value = self.frame.EvaluateExpression("lhs == rhs", options) self.assertTrue(value.GetError().Success(), "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.assertTrue( value.GetError().Success(), "GetCounter failed with error %s" % (value.GetError().GetCString())) 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.assertTrue(value.GetError().Success(), "1 == 2 expression couldn't run") self.assertTrue(value.GetSummary() == "false", "1 == 2 didn't return false.")
def test_swift_submodule_import(self): """Tests that swift expressions can import sub-modules correctly""" self.build() lldbutil.run_to_source_breakpoint( self, 'Set a breakpoint here', lldb.SBFileSpec('main.swift')) options = lldb.SBExpressionOptions() options.SetFetchDynamicValue(lldb.eDynamicCanRunTarget) # We'll be asked to auto-import Darwin.C when we evaluate this expression, # so even though it doesn't seem like it this does test auto-import: value = self.frame().EvaluateExpression("b", options) self.assertTrue(value.IsValid(), "Got a valid variable back from b") self.assertTrue(value.GetError().Success(), "And the variable was successfully evaluated") result = value.GetSummary() self.assertTrue( result == '"aa"', "And the variable's value was correct.") # Now make sure we can explicitly do the import: value = self.frame().EvaluateExpression('import Darwin.C\n b', options) self.assertTrue( value.IsValid(), "Got a valid value back from import Darwin.C") self.assertTrue( value.GetError().Success(), "The import was not successful: %s" % (value.GetError().GetCString()))
def do_test(self): """Tests that swift expressions resolve scoped variables correctly""" exe_name = "a.out" exe = os.path.join(os.getcwd(), exe_name) # Create the target target = self.dbg.CreateTarget(exe) self.target = target self.assertTrue(target, VALID_TARGET) # Set the breakpoints global_scope_bkpt = target.BreakpointCreateBySourceRegex( 'Set a breakpoint here to run expressions', self.main_source_spec) self.assertTrue(global_scope_bkpt.GetNumLocations() > 0, VALID_BREAKPOINT) # Launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, os.getcwd()) self.process = process self.assertTrue(process, PROCESS_IS_VALID) # Frame #0 should be at our breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint( process, global_scope_bkpt) self.assertTrue(len(threads) == 1) self.thread = threads[0] self.frame = self.thread.frames[0] self.assertTrue(self.frame, "Frame 0 is valid.") options = lldb.SBExpressionOptions() options.SetFetchDynamicValue(lldb.eDynamicCanRunTarget) # FIXME: pull the "try" back out when we fix <rdar://problem/21949031> enum_value = self.frame.EvaluateExpression("IThrowEnumOver10(101)", options) self.assertTrue(enum_value.IsValid(), "Got a valid enum value.") self.assertTrue( enum_value.GetError().Success(), "Got error %s getting enum value" % (enum_value.GetError().GetCString())) self.assertTrue( enum_value.GetValue() == "ImportantError", "Expected 'ImportantError', got %s" % (enum_value.GetValue())) object_value = self.frame.EvaluateExpression("IThrowObjectOver10(101)", options) self.assertTrue(object_value.IsValid(), "Got a valid object value.") self.assertTrue( object_value.GetError().Success(), "Got error %s getting object value" % (object_value.GetError().GetCString())) message = object_value.GetChildMemberWithName("m_message") self.assertTrue(message.IsValid(), "Found some m_message child.") self.assertTrue(message.GetError().Success(), "No errors fetching m_message value") self.assertTrue(message.GetSummary() == '"Over 100"', "Expected 'Over 100', got %s" % (message.GetSummary()))
def do_unwind_test(self, thread, bkpt, timeout): # # Use Python API to evaluate expressions while stopped in a stack frame. # main_frame = thread.GetFrameAtIndex(0) options = lldb.SBExpressionOptions() options.SetIgnoreBreakpoints(False) options.SetUnwindOnError(False) options.SetOneThreadTimeoutInMicroSeconds(timeout) val = main_frame.EvaluateExpression("a_function_to_call()", options) self.assertTrue(val.GetError().Fail(), "We did not complete the execution.") error_str = val.GetError().GetCString() self.assertTrue( "Execution was interrupted, reason: breakpoint" in error_str, "And the reason was right.") thread = lldbutil.get_one_thread_stopped_at_breakpoint( self.process(), bkpt) self.assertTrue(thread.IsValid(), "We are indeed stopped at our breakpoint") # Now unwind the expression, and make sure we got back to where we # started. error = thread.UnwindInnermostExpression() self.assertTrue(error.Success(), "We succeeded in unwinding") cur_frame = thread.GetFrameAtIndex(0) self.assertTrue(cur_frame.IsEqual(main_frame), "We got back to the main frame.")
def test_playgrounds(self): """Test that playgrounds work""" self.build() target = self.dbg.CreateTarget(self.getBuildArtifact("PlaygroundStub")) self.assertTrue(target, VALID_TARGET) self.registerSharedLibrariesWithTarget(target, ['libPlaygroundsRuntime.dylib']) lldbutil.run_to_source_breakpoint( self, 'Set breakpoint here', lldb.SBFileSpec('PlaygroundStub.swift'), exe_name="PlaygroundStub") contents = "" with open('Contents.swift', 'r') as contents_file: contents = contents_file.read() options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) options.SetPlaygroundTransformEnabled() self.frame().EvaluateExpression(contents, options) ret = self.frame().EvaluateExpression("get_output()") playground_output = ret.GetSummary() self.assertTrue(playground_output is not None) self.assertTrue("a=\\'3\\'" in playground_output) self.assertTrue("b=\\'5\\'" in playground_output) self.assertTrue("=\\'8\\'" in playground_output)
def _init_repl_process(self): self.debugger = lldb.SBDebugger.Create() self.debugger.SetAsync(False) if not self.debugger: raise Exception('Could not start debugger') # LLDB crashes while trying to load some Python stuff on Mac. Maybe # something is misconfigured? This works around the problem by telling # LLDB not to load the Python scripting stuff, which we don't use # anyways. self.debugger.SetScriptLanguage(lldb.eScriptLanguageNone) repl_swift = os.environ['REPL_SWIFT_PATH'] self.target = self.debugger.CreateTargetWithFileAndArch(repl_swift, '') if not self.target: raise Exception('Could not create target %s' % repl_swift) self.main_bp = self.target.BreakpointCreateByName( 'repl_main', self.target.GetExecutable().GetFilename()) if not self.main_bp: raise Exception('Could not set breakpoint') self.process = self.target.LaunchSimple(None, None, os.getcwd()) if not self.process: raise Exception('Could not launch process') self.expr_opts = lldb.SBExpressionOptions() swift_language = lldb.SBLanguageRuntime.GetLanguageTypeFromString( 'swift') self.expr_opts.SetLanguage(swift_language) self.expr_opts.SetREPLMode(True)
def setup_touch_highlighting(self, debugger): frame = self.debugger.GetSelectedTarget().GetProcess( ).GetSelectedThread().GetSelectedFrame() options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) expr = """ import UIKit extension UIWindow { public func highlight(_ point: CGPoint) { let circleView = UIView(frame: CGRect(x: 0, y: 0, width: %(size)i, height: %(size)i)) circleView.center = point circleView.alpha = 0.5 circleView.layer.cornerRadius = %(size)i/2 circleView.backgroundColor = UIColor.%(color)s circleView.isUserInteractionEnabled = false self.addSubview(circleView) UIView.animate(withDuration: %(duration)f, delay: 0.0, options: [], animations: { circleView.alpha = 0.0 }, completion: { (finished: Bool) in circleView.removeFromSuperview() }) } } """ % { 'size': 40, 'color': 'red', 'duration': 0.75 } frame.EvaluateExpression(expr, options)
def evaluate_expression(self, expression) -> Symbol: """ Wrapper for LLDB's EvaluateExpression. Used for quick code snippets. Feel free to use local variables inside the expression using format string. For example: currentDevice = objc_get_class('UIDevice').currentDevice evaluate_expression(f'[[{currentDevice} systemName] hasPrefix:@"2"]') :param expression: :return: returned symbol """ # prepending a prefix so LLDB knows to return an int type if isinstance(expression, int): formatted_expression = f'(intptr_t)0x{expression:x}' else: formatted_expression = str(expression) options = lldb.SBExpressionOptions() options.SetIgnoreBreakpoints(True) options.SetTryAllThreads(True) e = self.target.EvaluateExpression(formatted_expression) if not e.error.Success(): raise EvaluatingExpressionError(str(e.error)) return self.symbol(e.unsigned)
def static_type(self, test_call): self.get_to_bkpt("break here for static type") opts = lldb.SBExpressionOptions() if not test_call: # First see that we can print the function we were passed: result = self.frame.EvaluateExpression("fn", opts) error = result.GetError() self.assertTrue(error.Success(), "'fn' failed: %s" % (error.GetCString())) self.assertTrue( "() -> Swift.Int" in result.GetValue(), "Got the function name wrong: %s." % (result.GetValue())) self.assertTrue( "() -> Swift.Int" in result.GetTypeName(), "Got the function type wrong: %s." % (result.GetTypeName())) if test_call: # Now see that we can call it: result = self.frame.EvaluateExpression("fn()", opts) error.result.GetError() self.assertTrue(error.Success(), "'fn()' failed: %s" % (error.GetCString())) self.assertTrue(result.GetValue() == "3", "Got the wrong value: %s" % (result.GetValue()))
def test_top_level_expressions(self): self.build_and_run() resultFromCode = self.frame().EvaluateExpression( "doTest()").GetValueAsUnsigned() self.runCmd("kill") self.run_dummy() codeFile = open('test.cpp', 'r') expressions = [] current_expression = "" for line in codeFile: if line.startswith("// --"): expressions.append(current_expression) current_expression = "" else: current_expression += line options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeC_plus_plus) options.SetTopLevel(True) for expression in expressions: self.frame().EvaluateExpression(expression, options) resultFromTopLevel = self.frame().EvaluateExpression("doTest()") self.assertTrue(resultFromTopLevel.IsValid()) self.assertEqual(resultFromCode, resultFromTopLevel.GetValueAsUnsigned())
def test_playgrounds(self): """Test that playgrounds work""" self.build() lldbutil.run_to_source_breakpoint( self, 'Set breakpoint here', lldb.SBFileSpec('PlaygroundStub.swift'), exe_name="PlaygroundStub") contents = "" with open('Contents.swift', 'r') as contents_file: contents = contents_file.read() options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) options.SetPlaygroundTransformEnabled() self.frame().EvaluateExpression(contents, options) ret = self.frame().EvaluateExpression("get_output()") playground_output = ret.GetSummary() self.assertTrue(playground_output is not None) self.assertTrue("a=\\'3\\'" in playground_output) self.assertTrue("b=\\'5\\'" in playground_output) self.assertTrue("=\\'8\\'" in playground_output)
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 breakpoint_conditions_python(self): """Use Python APIs to set breakpoint conditions.""" target = self.createTestTarget() # Now create a breakpoint on main.c by name 'c'. breakpoint = target.BreakpointCreateByName('c', 'a.out') self.trace("breakpoint:", breakpoint) self.assertTrue(breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT) # We didn't associate a thread index with the breakpoint, so it should # be invalid. self.assertEqual(breakpoint.GetThreadIndex(), lldb.UINT32_MAX, "The thread index should be invalid") # The thread name should be invalid, too. self.assertTrue(breakpoint.GetThreadName() is None, "The thread name should be invalid") # Let's set the thread index for this breakpoint and verify that it is, # indeed, being set correctly. # There's only one thread for the process. breakpoint.SetThreadIndex(1) self.assertEqual(breakpoint.GetThreadIndex(), 1, "The thread index has been set correctly") # Get the breakpoint location from breakpoint after we verified that, # indeed, it has one location. location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) # Set the condition on the breakpoint location. location.SetCondition('val == 3') self.expect(location.GetCondition(), exe=False, startstr='val == 3') # 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) # Frame #0 should be on self.line1 and the break condition should hold. from lldbsuite.test.lldbutil import get_stopped_thread thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) self.assertTrue( thread.IsValid(), "There should be a thread stopped due to breakpoint condition") frame0 = thread.GetFrameAtIndex(0) var = frame0.FindValue('val', lldb.eValueTypeVariableArgument) self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and var.GetValue() == '3') # The hit count for the breakpoint should be 1. self.assertEqual(breakpoint.GetHitCount(), 1) # Test that the condition expression didn't create a result variable: options = lldb.SBExpressionOptions() value = frame0.EvaluateExpression("$0", options) self.assertTrue(value.GetError().Fail(), "Conditions should not make result variables.") process.Continue()
def swizzle(debugger, command, result, internal_dict): command_args = shlex.split(command) parser = generate_option_parser() try: (options, args) = parser.parse_args(command_args) except: result.SetError(parser.usage) return res = lldb.SBCommandReturnObject() interpreter = debugger.GetCommandInterpreter() expr_options = lldb.SBExpressionOptions() expr_options.SetIgnoreBreakpoints(True) expr_options.SetFetchDynamicValue(lldb.eNoDynamicValues) expr_options.SetTimeoutInMicroSeconds(30 * 1000 * 1000) # 30 second timeout expr_options.SetTryAllThreads(True) expr_options.SetUnwindOnError(True) expr_options.SetGenerateDebugInfo(True) expr_options.SetLanguage(lldb.eLanguageTypeObjC_plus_plus) expr_options.SetCoerceResultToId(True) frame = debugger.GetSelectedTarget().GetProcess().GetSelectedThread( ).GetSelectedFrame() command_script = generate_script(options) frame.EvaluateExpression(command_script, expr_options)
def handle_breakpoint(self, test, thread, breakpoint_id): if self.breakpoint.GetID() == breakpoint_id: frame = thread.GetSelectedFrame() if test.TraceOn(): print('Stopped at: %s' % frame) options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) options.SetREPLMode(True) options.SetFetchDynamicValue(lldb.eDynamicDontRunTarget) for expr_and_regexp in self.exprs_and_regexps: ret = frame.EvaluateExpression(expr_and_regexp['expr'], options) desc_stream = lldb.SBStream() ret.GetDescription(desc_stream) desc = desc_stream.GetData() if test.TraceOn(): print("%s --> %s" % (expr_and_regexp['expr'], desc)) for regexp in expr_and_regexp['regexps']: test.assertTrue( re.search(regexp, desc), "Output of REPL input\n" + expr_and_regexp['expr'] + "was\n" + desc + "which didn't match regexp " + regexp) return
def evaluate(expr): result = lldb.debugger.GetSelectedTarget().EvaluateExpression( expr, lldb.SBExpressionOptions()) evallog = "{} => {}".format(expr, result) log(evallog) exelog(evallog) return result
def test_expr_options_lang(self): """These expression language options should work as expected.""" self.build() # Set debugger into synchronous mode self.dbg.SetAsync(False) (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// breakpoint_in_main', self.main_source_spec) frame = thread.GetFrameAtIndex(0) options = lldb.SBExpressionOptions() # Make sure we can retrieve `id` variable if language is set to C++11: options.SetLanguage(lldb.eLanguageTypeC_plus_plus_11) val = frame.EvaluateExpression('id == 0', options) self.assertTrue(val.IsValid()) self.assertTrue(val.GetError().Success()) self.DebugSBValue(val) # Make sure we can't retrieve `id` variable if language is set to ObjC: options.SetLanguage(lldb.eLanguageTypeObjC) val = frame.EvaluateExpression('id == 0', options) self.assertTrue(val.IsValid()) self.assertFalse(val.GetError().Success())
def test_expr_options(self): """These expression command options should work as expected.""" self.build() # Set debugger into synchronous mode self.dbg.SetAsync(False) (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// breakpoint_in_main', self.main_source_spec) frame = thread.GetFrameAtIndex(0) options = lldb.SBExpressionOptions() # test --language on C++ expression using the SB API's # Make sure we can evaluate a C++11 expression. val = frame.EvaluateExpression('foo != nullptr') self.assertTrue(val.IsValid()) self.assertTrue(val.GetError().Success()) self.DebugSBValue(val) # Make sure it still works if language is set to C++11: options.SetLanguage(lldb.eLanguageTypeC_plus_plus_11) val = frame.EvaluateExpression('foo != nullptr', options) self.assertTrue(val.IsValid()) self.assertTrue(val.GetError().Success()) self.DebugSBValue(val) # Make sure it fails if language is set to C: options.SetLanguage(lldb.eLanguageTypeC) val = frame.EvaluateExpression('foo != nullptr', options) self.assertTrue(val.IsValid()) self.assertFalse(val.GetError().Success())
def load_lib_and_attach(debugger, command, result, internal_dict): import shlex args = shlex.split(command) dll = args[0] is_debug = args[1] python_code = args[2] show_debug_info = args[3] import lldb options = lldb.SBExpressionOptions() options.SetFetchDynamicValue() options.SetTryAllThreads(run_others=False) options.SetTimeoutInMicroSeconds(timeout=10000000) print(dll) target = debugger.GetSelectedTarget() res = target.EvaluateExpression("(void*)dlopen(\"%s\", 2);" % (dll), options) error = res.GetError() if error: print(error) print(python_code) res = target.EvaluateExpression( "(int)DoAttach(%s, \"%s\", %s);" % (is_debug, python_code.replace('"', "'"), show_debug_info), options) error = res.GetError() if error: print(error)
def do_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", self.main_source_file) self.assertEqual(bkpt.GetNumLocations(), 2, "Got two locations") # So now thread holds the main thread. Continue to hit the # breakpoint again on the spawned thread: threads = lldbutil.continue_to_breakpoint(process, bkpt) self.assertEqual(len(threads), 1, "Hit the breakpoint the second time") other_thread = threads[0] self.assertNotEqual(thread.GetThreadID(), other_thread.GetThreadID(), "A different thread") # Run an expression ONLY on other_thread. Don't let thread run: options = lldb.SBExpressionOptions() options.SetTryAllThreads(False) options.SetStopOthers(True) result = thread.frames[0].EvaluateExpression( '(int) printf("Hello\\n")', options) self.assertSuccess(result.GetError(), "Expression failed") stop_reason = other_thread.GetStopReason() self.assertStopReason( stop_reason, lldb.eStopReasonBreakpoint, "Still records stopped at breakpoint: %s" % (lldbutil.stop_reason_to_str(stop_reason))) self.assertEqual(other_thread.GetStopReasonDataAtIndex(0), 1, "Still records stopped at right breakpoint")
def test_no_crash_in_IR_arithmetic(self): """ Test that LLDB doesn't crash on evaluating specific expression involving pointer arithmetic and taking the address of a static class member. See https://bugs.llvm.org/show_bug.cgi?id=52449 """ self.build() lldbutil.run_to_source_breakpoint(self, "// stop in main", lldb.SBFileSpec("main.cpp")) # This expression contains the following IR code: # ... i64 ptrtoint (i32* @_ZN1A3s_cE to i64)) ... expr = "(int*)100 + (long long)(&A::s_c)" # The IR interpreter doesn't support non-const operands to the # `GetElementPtr` IR instruction, so verify that it correctly fails to # evaluate expression. opts = lldb.SBExpressionOptions() opts.SetAllowJIT(False) value = self.target().EvaluateExpression(expr, opts) self.assertTrue(value.GetError().Fail()) self.assertIn( "Can't evaluate the expression without a running target", value.GetError().GetCString()) # Evaluating the expression via JIT should work fine. value = self.target().EvaluateExpression(expr) self.assertSuccess(value.GetError())
def generateOptions(): expr_options = lldb.SBExpressionOptions() expr_options.SetUnwindOnError(True) expr_options.SetLanguage (lldb.eLanguageTypeObjC_plus_plus) expr_options.SetCoerceResultToId(True) expr_options.SetGenerateDebugInfo(True) return expr_options
def do_test(self, force_target): """Test that playgrounds work""" exe_name = "PlaygroundStub" exe = self.getBuildArtifact(exe_name) # Create the target if force_target: if lldb.remote_platform: triple = builder_darwin.construct_triple( configuration.lldb_platform_name, builder_darwin.getEffectiveArchitecture(None)) else: version, _, machine = platform.mac_ver() triple = '%s-apple-macosx%s' % (machine, version) target = self.dbg.CreateTargetWithFileAndArch(exe, str(triple)) else: target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) self.registerSharedLibrariesWithTarget(target, ['libPlaygroundsRuntime.dylib']) # Set the breakpoints breakpoint = target.BreakpointCreateBySourceRegex( 'Set breakpoint here', self.PlaygroundStub_source_spec) self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT) process = target.LaunchSimple(None, None, os.getcwd()) self.assertTrue(process, PROCESS_IS_VALID) threads = lldbutil.get_threads_stopped_at_breakpoint( process, breakpoint) self.assertEqual(len(threads), 1) contents = "" with open('Contents.swift', 'r') as contents_file: contents = contents_file.read() options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) options.SetPlaygroundTransformEnabled() self.frame().EvaluateExpression(contents, options) ret = self.frame().EvaluateExpression("get_output()") playground_output = ret.GetSummary() if not force_target: # This is expected to fail because the deployment target # is less than the availability of the function being # called. self.assertEqual(playground_output, '""') return self.assertTrue(playground_output is not None) self.assertTrue("a=\\'3\\'" in playground_output) self.assertTrue("b=\\'5\\'" in playground_output) self.assertTrue("=\\'8\\'" in playground_output) self.assertTrue("=\\'11\\'" in playground_output)