【问题标题】:How to add traceback/debugging capabilities to a language implemented in python?如何向用 python 实现的语言添加回溯/调试功能?
【发布时间】:2012-03-26 20:42:39
【问题描述】:

我正在使用 python 来实现另一种名为“foo”的编程语言。 foo 的所有代码都会被翻译成 python,并且也会在同一个 python 解释器中运行,所以它会 JIT 翻译成 python。

这是 foo 的一小段代码:

function bar(arg1, arg2) {
    while (arg1 > arg2) {
        arg2 += 5;
    }
    return arg2 - arg1;
}

这将转化为:

def _bar(arg1, arg2):
    while arg1 > arg2:
        arg2 += 5
        watchdog.switch()
    watchdog.switch()
    return arg2 - arg1

“看门狗”是一个 greenlet(生成的代码也在 greenlet 上下文中运行),它将监控/限制资源使用,因为该语言将运行不受信任的代码。

从示例中可以看出,在生成 python 代码之前,将对解析树进行小幅更改,以便添加看门狗开关并对函数标识符进行小幅更改。

为了满足所有需求,我还必须在语言中添加回溯/调试功能,这样当python运行时抛出异常时,用户将看到的是foo的代码回溯(而不是显示生成的python代码回溯)。

假设用户创建了一个名为“program.foo”的文件,其内容如下:

1  function bar() {
2      throw Exception('Some exception message');
3  }
4
5  function foo() {
6      output('invoking function bar');
7      bar();
8  }
9
10 foo();

这将转化为:

def _bar():
    watchdog.switch()
    raise Exception('Some exception message')

def _foo():
    print 'invoking function bar'
    watchdog.switch()
    _bar()

watchdog.switch()
_foo()

那么,'program.foo' 的输出应该是这样的:

invoking function bar
Traceback (most recent call last):
  File "program.foo", line 10
    foo();
  File "program.foo", line 7, inside function 'foo'
    bar();
  File "program.foo", line 2, inside function 'bar'
    throw Exception('Some exception message');
Exception: Some exception message

有没有简单的方法可以做到这一点?我更喜欢不涉及检测 python 字节码的解决方案,因为它在解释器实现的内部,但如果没有别的,那么检测字节码也会这样做。

【问题讨论】:

  • 您的翻译是否存储了 Python 代码行和 foo 代码行之间的任何类型的映射?您当然可以自定义回溯:IPython 有一个名为 ultratb 的模块,尽管它相当长且令人费解,并且可以进行一些清理。
  • 目前只做翻译。但如果它是解决方案的一部分,我当然可以将 python 行映射到 foo 行。

标签: python jit language-implementation


【解决方案1】:

您可以使用将上下文(文件名、函数、行号等)记录到全局堆栈的装饰器来装饰每个生成的 Python 函数。然后您可以派生自己的 Exception 类并在解释器的顶层捕获它。最后,您可以使用全局调试堆栈中的信息打印出您喜欢的内容。

【讨论】:

  • 这似乎是一个很好的线索。我可以调整这个解决方案,而不是装饰每个函数,我将在映射到它的每组 python 语句之前添加一个函数调用来记录当前的 foo 行。但是为什么我需要一个自定义异常类呢?难道我不能捕获任何 python 异常并在全局上下文堆栈中打印信息吗?
  • 当然可以。但是声明自己的异常类将允许您将一些自定义信息记录到异常中,具体到您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-07
  • 2020-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-10-16
  • 1970-01-01
相关资源
最近更新 更多