GDB体系结构(三)

4.9 与GDB的接口

GDB基本上是一个命令行调试器。随着时间的推移,人们已经尝试了各种方案,使其成为一个图形窗口调试器,但尽管所有的时间和精力,这些都没有被普遍接受。

命令行界面

命令行界面使用标准GNU库读取线来处理与用户的逐个字符交互。 Readline处理行编辑和命令完成等事情;用户可以执行诸如使用光标键返回到一行并修复字符之类的操作。

然后,GDB接受readline返回的命令,并使用命令表的级联结构进行查找,其中命令的每个连续字选择另一个表。例如,设置打印元件80涉及三个表;首先是所有命令的表,第二个是一个选项表可以被设置,并且第三是有价值的打印选项,其中的元素是限制从像的集合体的印刷对象的数目的一个表字符串或数组。一旦级联表调用了实际的命令处理函数,它就会获得控制权,并且参数解析完全取决于函数。一些命令,如跑,同样处理他们的论据传统的C ARGC / argv的标准,而另一些,如打印,假设该行的其余部分是一个单一的编程语言表达,给整条生产线转移到语言 - 特定的解析器。

机器接口

提供调试GUI的一种方法是使用GDB作为图形界面程序的一种“后端”,将鼠标点击转换为命令并将打印结果格式化为窗口。这已经被多次使用,包括KDbg和DDD(数据显示调试器),但它不是理想的方法,因为有时结果被格式化为人类可读性,省略细节并依赖于人类提供上下文的能力。

为了解决这个问题,GDB有一个备用的“用户”界面,简称机器界面或MI。它基本上仍然是一个命令行界面,但命令和结果都有额外的语法,使一切都显式 - 每个参数都用引号括起来,复杂的输出有子组的分隔符和组件的参数名。此外,MI命令可以使用在结果中回显的序列标识符作为前缀,确保报告的结果与正确的命令匹配。

要查看两种形式的比较方式,这是一个正常的步骤命令和GDB的响应:

(gdb) step

buggy_function (arg1=45, arg2=92) at ex.c:232
232  result = positive_variable * arg1 + arg2;

使用MI,输入和输出更加冗长,但其他软件更容易准确地解析:

4321-exec-step

4321^done,reason="end-stepping-range",
      frame={addr="0x00000000004004be",
             func="buggy_function",
             args=[{name="arg1",value="45"},
                   {name="arg2",value="92"}],
             file="ex.c",
             fullname="/home/sshebs/ex.c",
             line="232"}

Eclipse [ecl12]开发环境是MI最着名的客户端。

其他用户界面

其他前端包括一个名为GDBtk或Insight的基于tcl / tk的版本,以及一个名为TUI的基于curses的界面,最初由Hewlett-Packard提供。 GDBtk是使用tk库构建的传统多层图形界面,而TUI是分屏界面。

4.10 发展进程

维护者

作为一个原始的GNU程序,GDB开发遵循“大教堂”开发模式。最初由Stallman编写,然后GDB经历了一系列“维护者”,每个人都是架构师,补丁审阅者和发布经理的组合,只能访问少数Cygnus员工的源代码库。

1999年,GDB迁移到公共源代码库,并扩展到由数十名维护者组成的团队,由数十名拥有提交权限的人员提供帮助。这大大加速了开发,每周10次提交增长到100或更多。

测试测试

由于GDB是高度特定于系统的,在计算机中具有从最小到最大的系统的大量端口,并且具有数百个命令,选项和使用方式,即使是经验丰富的GDB黑客也难以预测所有变化的影响。

这就是测试套件的用武之地。测试套件包含许多测试程序和expect脚本,使用一个名为DejaGNU的基于tcl的测试框架。基本模型是每个脚本在调试测试程序,发送命令然后将输出与正则表达式进行模式匹配时驱动GDB。

该测试套件还能够对实时硬件和模拟器进行交叉调试,并具有特定于单一体系结构或配置的测试。

在2011年底,测试套件包括大约18,000个测试用例,包括基本功能测试,特定语言测试,体系结构特定测试和MI测试。其中大多数都是通用的,可以运行任何配置。预计GDB贡献者将在修补源上运行测试套件,并且不会观察到任何回归,并且预计新测试将伴随每个新功能。但是,由于没有人可以访问可能受更改影响的所有平台,因此很少能够获得零故障;对于为本机调试配置的中继快照,10--20次故障通常是合理的,而某些嵌入式目标将有更多故障。

4.11 得到教训

开放式发展胜利

GDB最初是“大教堂”开发过程的典范,其中维护者密切控制源,外部世界只通过定期快照看到进展。这是通过补丁提交的相对不足来合理化的,但封闭的过程实际上是在阻止补丁。由于采用了开放式过程,补丁的数量比以往任何时候都大得多,质量也一样好或更好。

制定计划,但期望改变

开源开发过程本质上有点混乱,因为不同的人在代码上工作了一段时间,然后消失了,让其他人继续。

但是,制定开发计划并发布它仍然是有意义的。它可以帮助指导开发人员处理相关任务,可以向潜在的资助者展示,并让志愿者思考他们可以做些什么来推进它。

但是不要试图强迫日期或时间框架;即使每个人都对一个方向充满热情,人们也不太可能保证全职工作的时间足够长,以便在选定的日期之前完成。

就此而言,如果计划已经过时,请不要坚持计划本身。很长一段时间,GDB有一个计划重组为一个libgdb库,它有一个定义良好的API,可以链接到其他程序(特别是那些带有GUI的程序);甚至更改了构建过程以构建libgdb.a作为中间步骤。虽然这个想法从那时起就定期出现,但Eclipse和MI的首要地位意味着图书馆的主要理由已被回避,截至2012年1月,我们已经放弃了图书馆的概念,并且正在摒弃现在毫无意义的代码。

如果我们无限智能,情况会很好

在看到我们做出的一些改变之后,您可能会想:为什么我们不首先做正确的事情?好吧,我们还不够聪明。

当然,我们可以预料到GDB将会非常受欢迎,并且将被移植到数十个和几十个本地和交叉架构中。如果我们知道这一点,我们可以从gdbarch对象开始,而不是花费数年时间来升级旧的宏和全局变量;同上目标向量。

当然,我们可以预期GDB将与GUI一起使用。毕竟在1986年,Mac和X Window系统已经出现了两年!我们可以将其设置为异步处理事件,而不是设计传统的命令接口。

真正的教训是,并非GDBers愚蠢,但我们不可能足够聪明地预测GDB将如何发展。 1986年,窗口和鼠标界面无处不在,一点也不清楚;如果GDB的第一个版本完全适合GUI使用,我们看起来就像天才一样,但它本来就是运气。相反,通过使GDB在更有限的范围内有用,我们构建了一个用户群,可以在以后进行更广泛的开发和重新设计。

学会过不完整的过渡

尝试完成过渡,但它们可能需要一段时间;期望和他们一起生活不完整。

在2003年的GCC峰会上,Zack Weinberg对海湾合作委员会的“不完整过渡”感到遗憾,其中引入了新的基础设施,但旧的基础设施无法移除。 GDB也有这些,但我们可以指出已经完成的一些转换,例如目标向量和gdbarch。即便如此,它们可能需要数年才能完成,同时必须保持调试器运行。

不要太依赖于代码

当你花费很长时间使用单一代码时,它是一个重要的程序,也支付账单,它很容易附加到它,甚至模拟你的思想以适应代码,而不是相反。

别。

代码中的所有内容都源于一系列有意识的决策:一些受到启发,有些受到启发。 1991年巧妙的节省空间的技巧与2011年的数GB RAM相比毫无意义。

GDB曾经支持Gould超级计算机。当他们在2000年左右关闭最后一台机器时,确实没有任何意义来保持这些位置。这一集是GDB过时流程的起源,现在大多数版本都包括某些部分的退役。

实际上,桌面上或已在进行中有许多根本性的变化,包括采用Python脚本编写,支持高度并行多核系统的调试,以及重新编码为C ++。这些变化可能需要数年才能完成;现在更有理由开始使用它们了。

原文链接

猜你喜欢

转载自blog.csdn.net/u013702678/article/details/83852692