代码之家  ›  专栏  ›  技术社区  ›  Kos

在gdb上编辑并继续

  •  20
  • Kos  · 技术社区  · 14 年前

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

    我的问题是: 我们是否会在gdb上使用e&c? 我知道这是一个特定于平台的特性,需要与编译器、调试器和操作系统进行认真的合作。 (MSVC有一个简单的方法,因为编译器和调试器总是在一个包中出现) 但是…它仍然应该是可行的。我甚至听说苹果在他们的GCC版本中实现了它。 [需要引文] . 我认为这确实可行。

    了解所有有关MSVC E&C的炒作(我的经验表明,当被问到这是MSVC用户首先提到的事情) “为什么不切换到eclipse和gcc/gdb” )我很惊讶,在很多年之后,gcc/gdb仍然没有这样的特性。有什么好的理由吗?我们说话的时候有人在处理吗?

    3 回复  |  直到 7 年前
        1
  •  16
  •   Jan Gray    14 年前

    这是一个惊人的非平凡的工作量,包括许多设计决策和特性权衡。考虑:您正在调试。德彪基被停职了。它在内存中的图像包含源的对象代码,以及对象、堆和堆栈的二进制布局。调试器正在检查其内存映像。它已经加载了有关符号、类型、地址映射、PC(IP)到源通信的调试信息。它显示调用堆栈、数据值。

    现在,您希望允许对代码和/或数据进行特定的可能编辑,而不必停止调试对象并重新启动。最简单的可能是将一行代码更改为另一行代码。也许您重新编译那个文件,或者只是那个函数,或者只是那个行。现在,您必须修补调试对象映像,以便在下一次跨过它或运行它时执行新的代码行。在引擎盖下如何工作?如果代码大于它所替换的代码行,会发生什么?它如何与编译器优化交互?也许您只能在专门为ENC调试目标编译的环境中执行此操作。也许您会限制可能的站点,这是合法的。考虑一下:如果您在调用堆栈中挂起的函数中编辑一行代码,会发生什么情况。当代码返回时,它运行的是函数的原始版本还是行更改后的版本?如果是原始版本,那么该源代码来自哪里?

    可以添加或删除本地变量吗?这对挂起的帧的调用堆栈有什么影响?当前函数的?

    你能更改函数签名吗?向对象添加字段/从对象中删除字段?现有实例呢?挂起的析构函数或终结器呢?等。

    要使任何一种可用的ENC工作,需要注意许多功能细节。然后有许多跨工具集成问题需要为PowerEnc提供基础结构。特别是,它有助于建立某种调试信息库,使调试信息和对象代码在编辑调试信息和对象代码之前和之后都可用。对于C++,PDBS中增量可更新的调试信息有帮助。增量链接也有帮助。

    从MS生态系统到GCC生态系统,很容易想象到GDB/GCC/Binutils中的复杂性和集成问题,无数的目标,一些需要ENC特定的目标抽象,以及ENC的“好但不重要”性质,这就是为什么它还没有出现在GDB/GCC中的原因。

    快乐黑客!

    (P.S.看看smalltalk-80交互式编程环境能做些什么,这很有启发性和启发性。在ST80中,没有“重新启动”的概念——如果您编辑了类的任何方面,您仍然需要继续运行,那么图像及其对象内存始终是活动的。在这样的环境中,对象版本控制不是一个假设。)

        2
  •  11
  •   Mohit    7 年前

    我不熟悉MSVC的E&C,但是GDB有一些您提到的事情:

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

    17。改变执行

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

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

    转让 :变量赋值
    跳跃的 :在其他地址继续
    信令 :给程序一个信号
    返回 :从函数返回
    打电话 :调用程序的函数
    修补 :修补程序
    编译和注入代码 :在gdb中编译和注入代码

        3
  •  3
  •   GravityWell    12 年前

    这是对“修复并继续”的旧苹果实现的一个很好的参考。它还引用了其他工作实现。

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

    下面是一个片段:

    Fix and Continue是许多其他调试器实现的功能, 我们为这个版本添加到了gdb中。SUN研讨会,SGI Prodev 车间,微软的Visual Studio,惠普的WDB,和Sun的热点Java 虚拟机都以某种方式提供这个特性。我以我们为基础 在HP WDB Fix and Continue功能上的实现 几年前增加了。尽管我的最终实现遵循 他们所采用的方法的概述,几乎没有共享 它们之间的代码。其中一些原因是建筑 不同之处(处理器和ABI),但更多的是 由于实现设计的差异。

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

    更新日期:2012年12月21日 有一个 GDB Roadmap PDF演示文稿,其中包括描述“修复并继续”以及其他要点的幻灯片。报告日期为2012年7月9日,因此可能有希望在某个时间添加此内容。演讲是 GNU Tools Cauldron 2012 .