【问题标题】:Continue after python-lldb script has finishedpython-lldb脚本完成后继续
【发布时间】:2020-10-05 08:59:13
【问题描述】:

在我的python-lldb 脚本完成后,有没有更好的方法来发出 continue 命令?

def HelloWorld(debugger, command, result, internal_dict):
    """
        HelloWorld function. It will print "Hello World", regardless of where lldb stopped.
        Auto-Continues after script has ran.
    """
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    print("[*] Hello World from :{}".format(process))
    process.Continue()

该示例将控制权交还给应用,但我不再拥有交互式 lldb 控制台。

此页面上的答案没有帮助: LLDB: silently continue after python script is done executing

旁注:如果我通过XCodeTerminal 附加,则行为相同。

【问题讨论】:

    标签: debugging lldb


    【解决方案1】:

    lldb 可以以“同步”或“异步”两种模式运行。

    在异步模式下,一旦被调试者开始执行,所有执行控制命令(step、next 等)都会完成并将控制权返回给 lldb。

    在同步模式下,执行控制命令等待进程停止后再返回。

    lldb 启发式地找出正确的同步/异步行为,但也可以使用SBDebugger.SetAsync API 手动设置。

    在执行 Python 支持的 lldb 命令时,lldb 会将自身设置为同步模式。这通常是您想要的,例如,如果您希望您的命令执行一个步骤,检查某些内容并执行另一个步骤,您不希望第一个 step 命令在过程中的实际步骤完成或您的“检查”之前返回某事”的行动会发生得太快。

    但是,如果您希望命令在继续后立即返回控制权,而不是等待进程停止,那么您可以在 Python 支持的命令中的最后一个 process.Continue() 之前调用 debugger.SetAsync(True)

    请注意,这个故事还有另一个复杂之处。当 lldb 启动进程时,默认行为是与被调试者共享终端。因此,当进程运行时,它将拥有终端,并且在进程停止之前,您不会看到 lldb 提示(这将覆盖进程输出)或有输入命令的方法。如果您想在进程运行时让调试器生效并接受命令,您需要为 lldb 和应用程序提供单独的终端。在 lldb 中,使用 process launch --tty,在 Xcode 中,运行方案的选项选项卡中有一组单选按钮,可让您选择单独的终端,而不是使用 Xcode 控制台。

    顺便说一句,从您的笔记中听起来好像您从 exe_ctx 参数(您在此版本中遗漏了)获得的过程对您不起作用?但也许这与其他问题混淆了。如果我在继续之前 SetAsync(True),那么继续 exe_ctx.process 对我来说很好。

    最后,如果你的 Python 命令确实将进程状态从停止切换到运行,你应该通过调用来告诉 lldb:

    result.SetStatus(lldb.eReturnStatusSuccessContinuingResult)
    

    result.SetStatus(lldb.eReturnStatusSuccessContinuingNoResult)
    

    如果您的命令在断点回调或停止挂钩中使用,这很重要,其中 lldb 使用结果来跟踪断点命令或停止挂钩是否强制重新启动目标。

    【讨论】:

    • 优秀的答案。我的 python 脚本运行并且它现在自动继续,正如我所期望的那样。感谢lldb.eReturnStatusSuccessContinuingResult 的提示。关于exe_ctx,我仍然需要了解获取SBFrame 实例的最佳方法是什么。我可以看到它可以从多个地方获得。例如frame = lldb.frame 或作为frame = exe_ctx.frame 传递给我的函数的函数参数。我会继续阅读lldb.llvm.org/python_reference/lldb.SBFrame-class.html
    • exe_ctx.frame 是正确的。您不能使用GetSelected API。当您的进程因为多个线程遇到断点而停止时,lldb 必须为每个停止的线程运行断点命令。它通过将适当的 exe_ctx 传递给断点回调中的命令来实现这一点,而不是在运行命令之前依次选择每个线程。因此,如果在这种情况下使用您的命令,GetSelected API 将不会做正确的事情。
    • 并且不要在命令/断点回调等中使用lldb.frame。这是 Python 模块中的全局变量,因此实际上无法在所有情况下可靠地设置。例如, lldb 一次可以支持多个目标,因此 lldb.frame 不能被赋予明确的含义。在您进入脚本解释器(使用script 命令)时将其设置为“当前选定的”目标->进程->线程->帧树是一种便利。在lldb的Python REPL中使用非常方便,但这是唯一有意义的上下文。
    猜你喜欢
    • 2013-12-08
    • 2013-02-11
    • 1970-01-01
    • 2016-10-03
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    相关资源
    最近更新 更多