在GDB上编辑并继续

Kos*_*Kos 20 c++ debugging gcc gdb edit-and-continue

我知道E&C是一个有争议的主题,有人说它鼓励一种错误的调试方法,但仍然 - 我认为我们可以同意很多情况下它显然是有用的 - 试验一些常量的不同值,重新设计GUI参数在飞行中找到一个好看的...你的名字.

我的问题是:我们是否会在GDB上进行E&C?我知道它是一个特定于平台的功能,需要与编译器,调试器和操作系统进行一些认真的合作(MSVC有一个简单,因为编译器和调试器总是在一个包中),但是......它仍然应该是可行的.我甚至听说过苹果公司在他们的GCC版本中实施了它[引证需要].而且我会说它确实可行.

知道关于MSVC的E&C的所有炒作(我的经验表明这是MSVC用户在被问及"为什么不切换到Eclipse和gcc/gdb"时首先提到的),我很惊讶,经过相当多年的GCC/GDB仍然没有有这样的功能.这有什么好的理由吗?我们说话的时候有人正在研究吗?

Jan*_*ray 16

这是一项令人惊讶的非常重要的工作,包括许多设计决策和功能权衡.考虑一下:你正在调试.该女神被停职.它在内存中的图像包含源的目标代码,以及对象,堆,堆栈的二进制布局.调试器正在检查其内存映像.它已经加载了有关符号,类型,地址映射,pc(ip)到源对应的调试信息.它显示调用堆栈,数据值.

现在,您希望允许对代码和/或数据进行一组特定的编辑,而无需停止调试对象并重新启动.最简单的可能是将一行代码更改为另一行.也许你重新编译该文件或只是那个函数或只是那一行.现在,您必须修补调试对象图像,以便在下次执行或以其他方式运行时执行该新代码行.这是如何工作的?如果代码大于它替换的代码行会发生什么?它如何与编译器优化交互?也许你只能在专门编译的EnC调试目标上执行此操作.也许您会限制可能的网站,这对EnC来说是合法的.考虑一下:如果您在调用堆栈中挂起的函数中编辑一行代码会发生什么.当代码返回时,它是否运行函数的原始版本或更改了行的版本?如果是原始版本,该来源的来源是什么?

你可以添加或删除本地人吗?这对挂起的帧的调用堆栈有什么影响?目前的功能?

你能改变功能签名吗?在对象中添加/删除字段?现有实例怎么样?那些未决的析构函数或终结函数呢?等等.

有很多很多功能细节可以用来制作任何可用的EnC工作.然后,有许多跨工具集成问题需要提供基础设施来为EnC供电.特别是,它有助于拥有某种调试信息存储库,可以将调试前和编辑后的调试信息和目标代码提供给调试器.对于C++,PDB中可逐步更新的调试信息有所帮助.增量链接也可能有所帮助.

从MS生态系统到GCC生态系统,很容易想象GDB/GCC/binutils的复杂性和集成问题,无数目标,一些需要EnC特定目标抽象,以及"很好但有不必要"的性质EnC的原因是GDB/GCC尚未出现的原因.

快乐的黑客!

(ps)看看Smalltalk-80交互式编程环境可以做些什么是有启发性和鼓舞人心的.在St80中没有"重启"的概念 - 如果您编辑了任何方面,图像及其对象存储器始终是实时的.你仍然必须继续运行.在这样的环境中,对象版本控制不是假设.)


Dmi*_*kov 11

我不熟悉MSVC的E&C,但是GDB有一些你提到过的东西:

http://sourceware.org/gdb/current/onlinedocs/gdb/Altering.html#Altering

17.改变执行

一旦您认为在程序中发现了错误,您可能想要确定是否纠正明显错误会导致其余运行中的正确结果.您可以通过实验找到答案,使用gdb功能来改变程序的执行.

例如,您可以将新值存储到变量或内存位置,为程序提供信号,在不同的地址重新启动它,甚至可以过早地从函数返回.

赋值:赋值给变量
跳转:继续在不同的地址发
信号:给程序一个信号
返回:从函数返回
调用:调用程序的函数
修补:修补程序
编译和注入代码:在GDB中编译和注入代码