如何最佳或适当地允许生成代码的调试?

4
出于各种原因,在一个项目中,我通过从各种源文件生成AST并将其编译为字节码来生成可执行代码(尽管这个问题也适用于直接生成字节码的情况,我想)。
经过一些实验,看起来调试器基本上只是使用嵌入在AST中的lineno信息和传递给compile的文件名来为调试器的目的提供表示,但是这假设被执行的代码来自单个磁盘文件。
对于我的项目来说,这不一定是这样的,可执行代码可以从多个来源拼凑而成,并且某些或所有这些来源可能已经从网络获取,或者从非磁盘存储(例如数据库)中检索出来。
因此,我的问题是:
  • 是否有可能提供某种类型的内存缓冲区,还是必须生成“虚拟源”的单个磁盘表示形式?
  • 如果虚拟源不能或不应该被线性化,调试器如何处理在不同的部分之间跳转?
  • 最后,Python是否仅支持单个连续源文件的假设是正确的,还是实际上可以以某种方式输入多个源?
例如,诸如网络风格文学编程之类的东西将以其原始形式进行调试,在代码部分之间跳转,而不是在所谓的“交错”形式中。
1个回答

2

一些问题可以通过trepan3k调试器来处理,其他问题则需要使用各种挂钩。

首先,它可以仅基于字节码进行调试。但是,如果行号表不存在,则无法执行步骤指令。因此,出于这个原因,我会为每个逻辑停止点(例如在语句的开头)添加一个“行号”。这些数字不必是行号,它们可以从1计数或是其他某个表格的索引。这更或多或少地类似于go的Pos类型位置。

调试器将允许您在函数上设置断点,但该函数必须存在。当您启动任何python程序时,大多数您定义的函数并不存在。因此,通常的方法是修改源代码,在某些时刻调用调试器。在trepan3k中,这个说法是:

from trepan.api import debug; debug()

在其他你想要中断并已经定义的函数所在的位置执行此操作。这些函数可以指定为现有变量上的方法,例如 self.my_function()
这个调试器的一个高级功能是将字节码反编译为源代码。有一个名为 deparse 的命令,它将显示您当前停留的位置周围的上下文。
虽然对字节码进行反编译有点困难,但根据您获得的字节码类型,结果可能会有所不同。
至于虚拟源问题,调试器在某种程度上容忍这种情况,因为在没有源时必须进行这种操作。为了方便远程调试(本地和远程文件位置可能不同),我们允许文件名重映射。
另一个库 pyficache 用于此重映射;我相信它具有将一个文件的连续行重新映射到另一个文件的能力。我认为你可以一次又一次地使用它。然而,到目前为止还没有这方面的需求。那段代码非常古老。所以有人必须加强 trepan3k 这里。
最后,与 trepan3k 相关的是一个名为 trepan-xpy 的 CPython 字节码调试器,即使行号表为空,它也可以步进字节码指令。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接