简介: IBM® Debugger 方案包装于一系列 IBM 软件开发产品之中。工具特定于一个交互性的源代码层次调试器,它可以帮助您去调试以各种语言写成的,并在不同的平台上运行的应用程序。IBM 调试器的关键特性在于,它的单个用户界面可以同时与不同的调试引擎相对话。调试引擎总是在不同的基本平台上运行,同时用户界面客户端则是在一个远程的机器上运行。调试引擎会通过一个网络连接来连接到用户界面客户端,以开始一次调试操作。本文向您展示了,怎样权衡这些核心特性,来帮助您改进软件开发的效率。
今天的软件开发机构面临很大的压力,去交付高质量的产品,尽可能地满足用户的需要。公司达到这个目标的一种方式,是权衡使用 IBM Debugger for AIX 以满足具有很大挑战性的质量目标,并提高它们的时间方案。本文将会向您展示怎样使用 IBM Debugger for AIX,走向成功。
IBM® Debugger for AIX 的构件组装到一系列 IBM 产品的同时,本文特定地关注于使用 IBM Debugger 与 IBM XL C/C++ 及 COBOL 对 AIX® 的汇编器。(查看本文结尾的 Resource 部分以得到使用 IBM Debugger for AIX 以及附加功能所包含的调试支持功能)。
IBM Debugger for AIX 允许您去调试以 C、C++ 和/或 COBOL 语言写成的调试 AIX 程序。用户界面客户端运行 Microsoft® Windows® 并通过一个网络连接远程地连接到一个在 AIX 上运行的调试器引擎。
IBM Debugger 工具使用一种客户端/服务器设计模型,其中用户界面客户端(UI)会连接到一个远程的调试引擎上,以建立一个调试操作。这种调试模型才是这种方案主要的优势所在。调试引擎就是调试调试“实际”工作的地方,例如,调试引擎会控制目标代码的执行,从目标的可执行负载模块中读取调试信息,设置中断点,评价表达式,并比较程序的指南。为了完成以上所有的工作,调试引擎必须有关于可执行调试格式的丰富知识,以及对其所运行环境的充分了解。
为了在源代码的层次上调试您的程序,您需要根据特定的汇编器选项来汇编程序,这些选项会指导生成符号化的信息,并调试对象文件中的 hook。对于 IBM XL C/C++ 汇编器 Enterprise Edition for AIX,使用优化(-O0)而是用 -g 选项来进行汇编。
UI 包含了监听调试引擎连接的 daemon。daemon 就是 UI 与 调试引擎之间的链接,并且必须在开始调试操作之前就得到配置。调试 daemon 会监听调试引擎连接的端口。为了开始调试,您需要确定 daemon 已经为接受连接做好了准备。您可以从 UI 中 Debug 视图工具栏中的 daemon 按钮来观察并更改 daemon 的状态。如果 daemon 正在监听,那么图标会显示为一个 。如果 daemon 没有进行监听,那么图标会显示为一个 。
daemon 使用的默认端口是 8001。如果您在一个多用户的机器上运行 UI,那么默认的 daemon 端口应该做好被不同调试操作使用的准备。如果您接受了一条信息,说调试操作不能开始,那么通过从 Debug Daemon 偏好页面或者从 Debug 视图中指定一个不同的端口号或者端口的范围,您可以更改 daemon 端口号。
通过分别启动 UI 与引擎,您可以对程序进行远程调试。在一个运行 Microsoft Windows 的系统上启动 UI,并使用一个在 AIX 上运行的远程调试引擎来连接到 UI 上。
执行下列的步骤来开始一个调试操作 :
- 启动客户端机器上的调试器用户界面。
在启动调试器用户界面时不要指定程序的名字。 - 确定调试 daemon 处于监听状态。
如果它尚未处于监听状态,那么您可以点击 daemon 图标来开始监听调试引擎连接。如果端口已经用于其它的引擎连接,那么您就需要更改端口号或者指定一个端口的范围了。如果您想得到更多的信息,那么您可以查看前一个界面,“创建 daemon”。 - 找到客户端机器的主机名或者 IP 地址。
所谓的客户端机器就是您运行调试器用户界面的机器。您可以选择 daemon 图标右边的向下箭头并从菜单中选择 Get Workstation IP 来找到客户端 IP 地址。您需要主机名或者客户端 IP 地址来启动调试引擎。 - 使用以下的命令行来启动调试引擎 :
$ irmtdbgc -qhost=[:port]
其中 daemon 主机是前步中您找到客户端机器的主机名或者 IP 地址。端口就是调试 daemon 所监听的端口号。
命令 irmtdbgc 支持一系列的命令行选项,并识别一系列的环境变量。例如,环境变量 DER_DBG_ADDR 包含了 -qhost 选项的默认值。您可以在命令行中输入 irmtdbgc -help 来得到怎样使用 irmtdbgc 的帮助。
一旦 UI 与调试引擎之间的连接建立了,那么您就可以开始调试您的源代码了。接下来的屏幕截图显示了调试操作的 UI,其中用户正在调试一个名为 sort 的程序:
调试器显示了大量的信息,并且可以分组到不同的称为视图的部分中。下面的部分将会讨论与各种调试相关任务最重要的核心。
您最喜欢使用到的视图是 Debug 视图,它是您的调试操作的主控制中心。除了 Debug 视图,UI 包含了一些其他的视图,以显示特定的信息,包含 Monitors、Breakpoints、Memory 与 Modules、Variables 及 Registers 视图。每一个视图中工具栏内的图标提供了附加的有用操作,而且您可以将鼠标置于其上,以显示一些描述操作的信息出来。如果您想了解更多的信息,那么您可以挨个地使用它们。
调试视图是任何调试过程的起始点。管理的调试视图会逐次添加每一个新的 UI 引擎连接。对于每一个调试下的过程,调试视图会显示所有它所运行的线程。反过来,对于每一个暂停的线程,可以看到一系列的栈框架,代表了访问的层级结构。除了调试视图,UI 还包含了一些其他的视图,来显示一些特定的信息,包含 Variables、Breakpoints、Registers、Monitors、Memory 与 Modules 视图。同样,当前开始调试的源文件会在 Source 编辑器中显示出来。几乎所有其他的视图都会取决于“活动的”调试过程。通过选择一个调试目标,或者调试视图中的任意其构件(例如,线程、栈框架),可以激活一个调试操作。当一个调试过程出于激活状态下,那么 UI 中剩余视图中的内容将会得到更新。
中断点视图是控制中断点的中心位置。您总是可以看到您在 Breakpoints 视图中设置的一系列中断点,并且可以右击视图并从 Add Breakpoint 子菜单中选择其中的一个来添加一个新中断点。通过禁止可以暂时性地将中断点置于非激活状态。在中断点视图中,激活中断点在旁边有一个可选的勾号,通过选中或者不选中可以激活或者禁止中断点的运行。
从第一个黄色的箭头开始,它们分别是:Step Into,Step Over 与 Step Return。
您还可以从运行菜单中得到这些命令,或者使用键盘快捷方式:F5、 F6 与 F7。如果您将程序指向 Run (F8), 执行会一直继续下去,直到达到了某一个中断点为止,或者程序终止为止。
每一次线程或者程序结束的时候,变量视图都会列出范围内的变量。
同样,在每一个程序暂停的时候,对界内变量所做的更改可以在变量视图中强调显示。在变量视图中有一些可用的操作。为了弄清楚可以执行什么操作,您可以在界面视图的任意一个地方右击,来打开内容菜单。变量值也可以在视图中得到更改,而且如果您从变量视图中更改了一个变量的话,那么分配的新值就会变得立即变得十分有效率了。您还可以更改变量的代表;例如,以二进制格式而不是默认的十进制形式来显示一个整数,使用某个选中变量的 Change representation 背景菜单可以完成此项操作。
一般条件下,您可以查看对调试来说十分关键的程序源代码。调试引擎会基于程序中的调试信息,来试着找到,或者“搜索”程序。这意味着调试引擎,基于存储在使用 -g 选项汇编程序中的文件路径信息,将会试着找到服务器上的源代码。如果调试引擎不能使用调试信息来找到程序的源代码,那么您可以编辑查找路径。这是一系列位置的列表,调试引擎可以从中进行搜索以找到丢失的源代码。通过编辑源代码的查找路径,您可以将调试器指向更多位置处丢失的源代码处。通过从调试视图中程序的背景菜单中选择 Edit Source Lookup... 条目,您可以实现这一点。
除了显示源文件,还有其他的两个选项可以查看调试器源文件;您可以选择以分别显示程序,或者分布显示,或者您可以使用混合视图以显示源文件,并同时显示程序。调试器帮助文件包含了怎样为您的程序选择最佳操作的指南。注意分别操作或者混合视图都是根据集合指南来完成的,尽管源文件的处理是通过声明来实现的 。
有时您可能发现您的程序运行了一个您很感兴趣的点,而您需要重启您的调试操作。幸运的是,这一步可以完成,甚至不用去暂停 UI 的友好完善操作。在您感兴趣的点上简单地设置一个中断点,您只须点击 Restart program 按钮,并运行程序,直到达到中断点为止。
调试器 UI 构建于 Eclipse 开源语言上,并且可以从其高级帮助系统中获益。例如,将您的鼠标停留在一个工具栏按钮上,将会显示出关于该工具的提示信息,而且您点击 F1 按钮将会产生视图的背景相关性帮助文件。
从背景菜单中选择 Key assist... 条目是查看所有可用快捷方式的一种方法。
这部分将会讨论 IBM 调试器工具中可用的更多高级特性。它们可以支持更快的问题解决方法,并实现使用 IBM 调试器的主要优势。
有时有一段代码会得到多次的重复访问,有时甚重由不同的线程访问,但是如果达到某种特定的状况时,您只想停止其中的一段代码。此时就是中断点向导的状况页面大有用武之地的地方了。第二个,可选性页面(您可以从主页面中选择 Next 而不是 Finish 来打开该页面)允许您去处理这种情况。您还可以控制您想要终止的线程,中断的频率,甚重定义在中断以后必须为真的逻辑表达式。在同一位置处您还可能拥有多个状况性的中断点;它们可以从中断点视图中得到轻松激活或者禁止。
AIX 工具的 IBM 调试器提供了以下的中断点类型。
- Address:当执行指针达到程序中一个特定的地址时会暂停一个程序。当您从单独或者混合模式下的源视图中设置一个中断点,也可以创建一个中断点类型。这就允许您进一步完善地指定调试器应该在什么地方中断。
- Entry:当执行将要输入给定的函数时暂停程序。可以在 Modules 视图中右击一个条目来创建这种类型的中断点。如果函数在模块视图中没有进行监听,因为可执行的包含部分没有得到载入,那么您就可以创建一个进入中断点。
- Line:当执行达到给定的源代码行时暂停程序,也可以从源视图中进行创建。您可以为尚未达到的位置及尚未载入的模块设置行与条目。查看文献以得到关于怎样去做的具体指导信息。
- Load: 当载入给定的库时暂停程序。
- Watch:当内存指定的部分发生改变时暂停程序。
所有中断点都可以从中断点视图内容菜单中得到创建。
模块视图提供了用于创建程序的源文件的代表,包括它们所提供的函数定义。从模块视图中打开这些文件来在源文件编辑器中查看它们。右击视图中的函数元素来设置中断点。
监视器视图允许您轻松地访问并更改您所感兴趣的变量。例如,每一次程序暂停时,您都可以检查特定变量或者表达式的值,您可以为变量或者表达式创建一个监视器,而且该监视器稍后在监视器视图中可以看到。对于查看一些全局性变量来时十分有用,因为它们会在调试过程中发生变更。您可以监视任意有效的表达式,例如简单的局域变量,以及一个数组中的特定索引。
在下面的一个范例中,假设您在程序的第 22 行中有一个中断点。不管何时触动了该中断点,您都可以决定 i 是奇数的还是偶数的。
为了完成此项操作,您可以为表达式 "(i % 2) == 0". 添加一个表达式。实现这一点有很多种方式。在编辑器中,您可以右击表达式,右击,并从弹出菜单中选择 Monitor Expression。
在每一步之后,监视器的值都会得到更新,而且一旦它被改动了,那么可以轻松地识别出来。您有好几种方式来添加监视器:您可以从变量视图或者监视器视图通过点击监视器视图中的 按钮,并输入要监视的表达式,来监视一个局域变量。
如果您想要监视一个或者多个全局性变量,那么您可以从监视器视图的内容菜单中选择 Select Globals list 来从全局性变量中的列表中选择一个。您还可以从监视器视图中更改一个监视变量的值,而且这种更改是十分有效的。
内存视图允许您去检查并更改特定地址处内存的内容,通常是一个变量。您还可以选择内存以什么格式显示:十六进制、ASCII、EBCDIC、整数。其中地址用作表达式基础的表达式叫做内存监视器,而且您可以使用内存视图中的监视器窗格来添加和删除内存监视器。注意内存监视器不同于监视器视图中使用的监视器以及前文讨论过的监视器。
下面的图片向您展示了名为“it”的变量的 Signed Integer 内存赋值。变量在内存中的地址是 0x2FF22938,而它当前的值则是 10。
您可以同时查看不同格式的内存的内容。
内存视图中一个有用的特性便是内容菜单中的 Reset to Base Address 操作。如果您从赋值的起始地址处移开了,那么您可以使用该操作来轻松跳到该位置处。
内存映射特性能够使您根据 XML 文件中所定义的布局来显示内存的某个区域。这是十分有用的,例如,如果您想要显示在程序外部定义的内存块,那么就可以用到上述特性了。
为了创建一个内存映射赋值,您需要在定义您想要使用的布局的文件系统上选择文件。您可以按照以下方法来为变量创建一个映射:在 Variables 或者 Monitors 视图中选择变量或者监视器,并从背景菜单中选择 Monitor Memory > Map... ,然后浏览以选择 XML 文件作为映射的布局使用。这将会(a)为 Memory 视图中的变量创建一个新的内存监视器,并(b)使用该文件创建一个新的内存映射复制。
在一个简单的实例中,内存映射工具使您能够为一个复杂的变量定义一个布局,例如一个集团或者一个结构。
查看以下的结构:
typedef struct { unsigned short ushort_val; short short_val; unsigned long ulong_val; long long_val; char string_val[12]; char char_val; } _test; |
相应的布局文件应该如下所示 :
<?xml version="1.0"?> |
这要比其他的赋值类型更加有用,因为它支持去检查内存的逻辑性结构。每一个“字段”都定义了内存 1 的命名区域或者更多的比特,以及一个在程序内容中有意义的可选文本描述。类型属性用于指示内存应该怎样赋值,以十六进制、十进制、ASCII 等等格式。还有一个好处是,内存映射可以沿着一个大概的、基于列的赋值处显示。
使用以上的 XML 文件,下面的屏幕截图会显示该结构实例的内存映射,如下所示。
查看一下具体的内存映射赋值,您可以看到有一些列提供了关于每一个字段的具体信息。
Value 列为每一个区域显示了内存的内容。而 Offset 列则显示了每一个区域的偏移。Description 列显示了用户提供的关于每一个区域的信息。对于添加额外的信息,这一点是十分有用的,特别是如果映射在开发员之间进行共享的话更是这样。描述可以得到编辑以进行赋值,而新的描述可以有选择性地自动保存到相应的 XML 文件中。为了激活该项特性,您可以从内存视图页面中打开 Memory 映射偏好页面,并确定 当编辑组与描述时,总是将更改保存到页面中 旁边的框框被选中了 。
为了更加容易的识别,内存赋值使用演示指示器来强调显示一个或者多个经过变更之后的比特。您还可以拥有同时显示的两个不同的赋值,一边一个,如下图所示 。
左边的区域,被标记为“A”,它是监视器赋值所用的内存映射,同时右边的赋值区域,被标记为“B”,它包含了内存中相同区域内的整数代表。这就允许您使用内容映射来查看内存块的逻辑排列,以及结构之前及之后内存的内容。
内存映射工具有其他的特性或者使用,而且通过咨询官方的文件文献,您还可以学到更多的关于它们的知识。
您可以使用注册表视图,来检查和编辑不同注册表的内容。程序中的注册器被分为了三组:General、Floating Point 以及 Special Purpose。特定目的的注册器是系统定义的,屏幕界面中所列出的注册器是针对 AIX 的。IAR,也就是 Instruction Address Register,包含了当前指南的地址,这就是说,关于执行的指南。注册器视图类似于变量视图,在这个视图中通过强调更改项来指示更改的注册。注册也可以添加到监视器视图中以查看更改。而且,可以使用内存视图来查看它们的内存。
调试操控台支持对已存在的调试操作的命令行进行调试。您可以直接使用调试引擎来进行调试,并在调试操控台上查看得到的结果,这有助于进行互动性的交流。支持的命令是调试引擎附件,而且在 AIX 上,通过在调试操控台上输入“help”可以来将其显示出来。
在 AIX 上,您可以激活“echo”功能,而且稍后您输入的命令可以导出或者导入。这就允许您将您所做的操作“记录”到调试器中,并且生成一个可以重复使用的脚本以让您所调试的程序置于您想要的状态。在下面的屏幕截图中,右边的列就是命令列窗格,它是您所输入的所有命令的列表,而左边的列是命令历史窗格,它显示了输入命令的输出。您可以使用工具栏按钮来清除命令历史以及列表窗格,命令的导入、导出以及运行列表。
不管您是怎样启动一次调试过程的(通过命令行或者一个对话框),调试器 UI 都可以同时主宰任意数量的调试过程。正如您在前面提到的那样,每一个新的调试过程都由调试视图中的一个调试目标所代表。几乎所有其他视图的内容,包括源代码编辑器、监视器、注册表、模块、变量和内存视图,都会基于活动调试过程来得到更新。在调试视图中更改选择的调试目标,将会在操作之间进行切换,并更新剩余的视图。接下来的屏幕截图显示了带有两个调试操作的调试器。
IBM 调试器工具支持在一些平台上,在单个调试器用户界面中调试以多种不同编程语言写成的程序。除了基本的调试功能,例如设置行中断点,该工具提供了一些高级的特性,包括内存映射、远程重启以及多个中断类型。为了平衡这些属性之间的使用,您可以查看 IBM Debugger 文献,以得到关于这些特性以及其他特性的进一步详细解释。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14780873/viewspace-670087/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/14780873/viewspace-670087/