在GDB上编辑并继续

时间:2010-11-29 12:16:02

标签: c++ debugging gcc gdb edit-and-continue

我知道E& C是一个有争议的话题,有些人说它鼓励采用错误的调试方法,但仍然 - 我认为我们可以同意有很多案例,当它显然有用时 - 试验一些不同的值常数,即时重新设计GUI参数以找到一个好看的...你的名字。

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

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

3 个答案:

答案 0 :(得分:16)

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

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

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

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

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

从MS生态系统到GCC生态系统,很容易想象GDB / GCC / binutils的复杂性和集成问题,无数目标,一些需要EnC特定目标抽象,以及“很高兴但是非必要的“EnC的本质,这就是GDB / GCC尚未出现的原因。

快乐的黑客攻击!

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

答案 1 :(得分:11)

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

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

  

<强> 17。改变执行

     

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

     

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

     

作业:对变量的分配
  跳跃:继续在不同的地址
  信号:为您的程序提供信号   返回:从功能返回
  致电:调用程序的功能
  修补:修补程序
  编译和注入代码:在GDB中编译和注入代码

答案 2 :(得分:3)

这是旧Apple实施“修复并继续”的很好的参考。它还引用了其他工作实现。

http://sources.redhat.com/ml/gdb/2003-06/msg00500.html

这是一个片段:

  

Fix and continue是许多其他调试器实现的功能,   我们在此版本中添加到我们的gdb中。 Sun研讨会,SGI ProDev   WorkShop,微软的Visual Studio,HP的wdb和Sun的Hotspot Java   VM都以这种或那种方式提供此功能。我以我们为基础   在他们的HP wdb修复和继续功能上实现   几年前补充道。虽然我的最终实施遵循了   他们采取的方法概述,几乎没有共享   他们之间的代码。其中一些是因为建筑学   差异(处理器和ABI),但更多的是   由于实施设计的差异。

请注意,此功能可能已在其工具链的更高版本中删除。

更新:2012年12月21日 有一个GDB Roadmap PDF演示文稿,其中包含一个描述“修复并继续”的幻灯片以及其他要点。该演示文稿的日期是2012年7月9日,所以也许有希望在某些时候添加这个。该演示文稿是GNU Tools Cauldron 2012

的一部分