在 GDB 上编辑并继续
我知道 E&C 是一个有争议的主题,有人说它鼓励错误的调试方法,但我仍然认为我们可以同意,在很多情况下它显然是有用的 - 尝试某些常量的不同值,重新设计动态 GUI 参数可以很好地查找...您能想到的。
我的问题是:我们会在 GDB 上进行 E&C 吗?我知道这是一个特定于平台的功能,需要与编译器、调试器和操作系统认真合作 (MSVC 很容易做到这一点,因为编译器和调试器总是在一个包中),但是......它仍然应该是可行的。我什至听说 Apple 在他们的 GCC 版本中实现了它[需要引用]。我想说这确实是可行的。
了解有关 MSVC 的 E&C 的所有宣传(我的经验表明,当 MSVC 用户被问到“为什么不切换到 Eclipse 和 gcc/gdb”时,这是第一件事),我非常惊讶,在有些年GCC/GDB仍然没有这样的功能。这有什么好的理由吗?在我们说话的时候有人在做这件事吗?
I know that E&C is a controversial subject and some say that it encourages a wrong approach to debugging, but still - I think we can agree that there are numerous cases when it is clearly useful - experimenting with different values of some constants, redesigning GUI parameters on-the-fly to find a good look... You name it.
My question is: Are we ever going to have E&C on GDB? I understand that it is a platform-specific feature and needs some serious cooperation with the compiler, the debugger and the OS (MSVC has this one easy as the compiler and debugger always come in one package), but... It still should be doable. I've even heard something about Apple having it implemented in their version of GCC [citation needed]. And I'd say it is indeed feasible.
Knowing all the hype about MSVC's E&C (my experience says it's the first thing MSVC users mention when asked "why not switch to Eclipse and gcc/gdb"), I'm seriously surprised that after quite some years GCC/GDB still doesn't have such feature. Are there any good reasons for that? Is someone working on it as we speak?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一项令人惊讶的不平凡的工作量,包含许多设计决策和功能权衡。考虑一下:您正在调试。被调试者被暂停。它在内存中的映像包含源的目标代码、对象的二进制布局、堆、堆栈。调试器正在检查其内存映像。它已加载有关符号、类型、地址映射、pc (ip) 到源对应关系的调试信息。它显示调用堆栈、数据值。
现在您希望允许对代码和/或数据进行一组特定的可能编辑,而无需停止调试程序并重新启动。最简单的可能是将一行代码更改为另一行。也许您重新编译该文件或仅重新编译该函数或仅重新编译该行。现在,您必须修补调试对象图像,以便在下次单步执行它或以其他方式运行它时执行该新代码行。它在幕后是如何工作的?如果代码比它替换的代码行大,会发生什么?它如何与编译器优化交互?也许您只能在专门为 EnC 调试目标编译的目标上执行此操作。也许您会限制 EnC 合法的可能站点。考虑一下:如果您编辑挂起在调用堆栈中的函数中的一行代码,会发生什么情况。当代码返回时,它会运行该函数的原始版本还是您的行已更改的版本?如果是原始版本,该来源来自哪里?
您可以添加或删除当地人吗?这对挂起帧的调用堆栈有什么作用?当前功能?
您可以更改函数签名吗?向对象添加字段/从对象中删除字段?现有实例怎么样?未决的析构函数或终结器怎么样?等等。
要使任何类型的可用 EnC 正常工作,需要注意很多很多功能细节。此外,还需要解决许多跨工具集成问题,以提供支持 EnC 的基础设施。特别是,它有助于拥有某种调试信息存储库,可以为调试器提供编辑前后的调试信息和目标代码。对于 C++,PDB 中可增量更新的调试信息会有所帮助。增量链接也可能有所帮助。
从 MS 生态系统到 GCC 生态系统,很容易想象 GDB/GCC/binutils 的复杂性和集成问题、无数的目标、一些需要的 EnC 特定目标抽象,以及“有很好但无关紧要”的性质EnC 的原因是它还没有出现在 GDB/GCC 中。
快乐黑客!
(ps)看看 Smalltalk-80 交互式编程环境可以做什么是有启发性和启发性的。在 St80 中没有“重新启动”的概念——如果您编辑了图像的任何方面,图像及其对象内存总是活动的。在这样的环境中,你仍然必须继续运行类,对象版本控制不是一个假设。)
It is a surprisingly non-trivial amount of work, encompassing many design decisions and feature tradeoffs. Consider: you are debugging. The debugee is suspended. Its image in memory contains the object code of the source, and the binary layout of objects, the heap, the stacks. The debugger is inspecting its memory image. It has loaded debug information about the symbols, types, address mappings, pc (ip) to source correspondences. It displays the call stack, data values.
Now you want to allow a particular set of possible edits to the code and/or data, without stopping the debuggee and restarting. The simplest might be to change one line of code to another. Perhaps you recompile that file or just that function or just that line. Now you have to patch the debuggee image to execute that new line of code the next time you step over it or otherwise run through it. How does that work under the hood? What happens if the code is larger than the line of code it replaced? How does it interact with compiler optimizations? Perhaps you can only do this on a specially compiled for EnC debugging target. Perhaps you will constrain possible sites it is legal to EnC. Consider: what happens if you edit a line of code in a function suspended down in the call stack. When the code returns there does it run the original version of the function or the version with your line changed? If the original version, where does that source come from?
Can you add or remove locals? What does that do to the call stack of suspended frames? Of the current function?
Can you change function signatures? Add fields to / remove fields from objects? What about existing instances? What about pending destructors or finalizers? Etc.
There are many, many functionality details to attend to to make any kind of usuable EnC work. Then there are many cross-tools integration issues necessary to provide the infrastructure to power EnC. In particular, it helps to have some kind of repository of debug information that can make available the before- and after-edit debug information and object code to the debugger. For C++, the incrementally updatable debug information in PDBs helps. Incremental linking may help too.
Looking from the MS ecosystem over into the GCC ecosystem, it is easy to imagine the complexity and integration issues across GDB/GCC/binutils, the myriad of targets, some needed EnC specific target abstractions, and the "nice to have but inessential" nature of EnC, are why it has not appeared yet in GDB/GCC.
Happy hacking!
(p.s. It is instructive and inspiring to look at what the Smalltalk-80 interactive programming environment could do. In St80 there was no concept of "restart" -- the image and its object memory were always live, if you edited any aspect of a class you still had to keep running. In such environments object versioning was not a hypothetical.)
我不熟悉 MSVC 的 E&C,但 GDB 有一些你提到过的东西:
http://sourceware.org/gdb/current/onlinedocs/gdb/Altering.html#Altering
I'm not familiar with MSVC's E&C, but GDB has some of the things you've mentioned:
http://sourceware.org/gdb/current/onlinedocs/gdb/Altering.html#Altering
这是对旧的 Apple 实现“修复并继续”的一个很好的参考。它还引用了其他工作实现。
http://sources.redhat.com/ml/gdb/2003- 06/msg00500.html
这是一个片段:
请注意,此功能可能已在其工具链的更高版本中删除。
更新:2012 年 12 月 21 日
有一个 GDB 路线图 PDF演示文稿,其中包括一张描述“修复并继续”以及其他要点的幻灯片。该演示文稿的日期为 2012 年 7 月 9 日,因此也许有希望在某个时候添加此内容。该演示文稿是 GNU Tools Cauldron 2012 的一部分。
另外,我知道将 E&C 添加到 GDB 或 Linux 领域的任何地方对于所有不同的组件来说都是一项艰巨的任务。
但我不认为 E&C 有争议。我记得在 VB5 和 VB6 中使用过它,并且可能在那之前就已经存在了。而且它很早就存在于 Office VBA 中。自 VS2005 起它就出现在 Visual Studio 中。 VS2003 是唯一一个没有它的版本,我记得开发人员对此大喊大叫。无论如何,他们打算将其添加回来,并且他们在 VS2005 中做到了,并且从那时起它就一直存在。它适用于 C#、VB、C 和 C++。它在 MS 核心工具中已经存在了 20 多年,几乎是连续的(算上独立时的 VB),并且减去 VS2003。但你仍然可以说他们在 VS2003 时期就在 Office VBA 中拥有了它;)
Jetbrains 最近也将其添加到了他们的 C# 工具 Rider 中。他们在 Rider 博客中吹嘘了这一点(在我看来,这是正确的)。
This is a pretty good reference to the old Apple implementation of "fix and continue". It also references other working implementations.
http://sources.redhat.com/ml/gdb/2003-06/msg00500.html
Here is a snippet:
Note that this capability may have been removed in a later version of their toolchain.
UPDATE: Dec-21-2012
There is a GDB Roadmap PDF presentation that includes a slide describing "Fix and Continue" among other bullet points. The presentation is dated July-9-2012 so maybe there is hope to have this added at some point. The presentation was part of the GNU Tools Cauldron 2012.
Also, I get it that adding E&C to GDB or anywhere in Linux land is a tough chore with all the different components.
But I don't see E&C as controversial. I remember using it in VB5 and VB6 and it was probably there before that. Also it's been in Office VBA since way back. And it's been in Visual Studio since VS2005. VS2003 was the only one that didn't have it and I remember devs howling about it. They intended to add it back anyway and they did with VS2005 and it's been there since. It works with C#, VB, and also C and C++. It's been in MS core tools for 20+ years, almost continuous (counting VB when it was standalone), and subtracting VS2003. But you could still say they had it in Office VBA during the VS2003 period ;)
And Jetbrains recently added it too their C# tool Rider. They bragged about it (rightly so imo) in their Rider blog.