【问题标题】:Sandboxed code evaluation during a breakpoint session断点会话期间的沙盒代码评估
【发布时间】:2020-07-30 07:09:23
【问题描述】:

假设我在代码中的以下if 语句上设置断点并在 Python 调试器中启动调试会话(例如pdb):

if <statement> and <...>:  <- Current location of debugger in a debugging session
  // Do something

我想以交互方式询问调试器(在断点的上下文中)&lt;statement&gt; 将在程序中返回的布尔值,就好像我在继续执行之前从未运行过该语句一样调试会话上下文中的程序。

请注意,&lt;statement&gt; 当然可能会更改 Python 变量(可变值),而且它可能不是是幂等操作。

VSCode 是否支持这种类型的“安全调试”?请注意,这不仅适用于 if 语句,还适用于任何代码。

我假设这些类型的调试检查可能需要“快照”所有流程变量(或可能受statement 影响的变量)以防万一,我不知道这是否是 VSCode 调试器(或一般现代调试器)支持。

【问题讨论】:

  • 我不是专家的声音,但使用 Visual Studio Code 集成调试器我从来没有遇到过任何麻烦。
  • 您是否知道一种检查活动对象堆栈或查看条件值的方法,例如if &lt;expr&gt;?我不相信 cpython 使对象堆栈可供调试器检查。

标签: python-3.x debugging visual-studio-code pdb


【解决方案1】:

为了提供一些见解,请考虑这种语句的执行方式:

import dis
def f(a, b):
    if a and b:
        print()
dis.dis(f)

这编译成以下字节码:

  5           0 LOAD_FAST                0 (a)
              2 POP_JUMP_IF_FALSE       14
              4 LOAD_FAST                1 (b)
              6 POP_JUMP_IF_FALSE       14

  6           8 LOAD_GLOBAL              0 (print)
             10 CALL_FUNCTION            0

因此,在任何if 块执行之前,在 if 语句暂停处设置断点,为了读取a 的值(第一个条件),调试器需要向前执行在第一个暂停的指令POP_JUMP_IF_FALSE 然后读取栈顶的值。理论上这是可能的,但有点奇怪的是,一旦它超过第一个 POP_JUMP_IF_FALSE,该值就不再可访问,因为该指令会将其从堆栈中删除。

通常我相信调试器(至少在行号处使用断点的调试器)将同一行上的所有步骤视为一个步骤,因此它会一次性执行所有指令,直到 LOAD_GLOBAL允许读取中间值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多