本附录重点说明 dbx 的使用方法以及在 dbx 下运行程序时更改程序或更改程序行为的命令,并与不使用 dbx 运行程序进行了比较。了解哪些命令可能修改程序是很有必要的。
本章由以下部分组成:
可以使用 dbx 观察进程,并且不会对进程造成影响。但有时可能会彻底修改进程的状态。而且有时,普通的观察可能会影响执行,导致出现错误症状而失去控制。
在 dbx 下运行时,应用程序的行为方式可能会不同。尽管 dbx 尽量减小它对所调试的程序的影响,但您还是应该注意以下问题:
您可能忘记去掉 -C 或禁用 RTC。将 RTC 支持库 librtc.so 装入程序可能导致程序的行为方式不同。
dbx 初始化脚本可能含有一些您已经忘记的环境变量集。在 dbx 下运行时,栈基址从不同的地址开始。它视环境及 argv[] 的内容的不同而异,从而强制局部变量以不同方式分配。如果它们未初始化,则将获得不同的随机数字。可以使用运行时检查来检测此问题。
程序不会在使用前对通过 malloc() 分配的内存进行初始化,这与前者的情况类似。可以使用运行时检查来检测此问题。
dbx 必须捕捉 LWP 创建和 dlopen 事件,这可能会影响与计时有关的多线程应用程序。
dbx 会在收到信号时执行上下文切换,因此,如果应用程序大量使用信号,则系统工作情况可能会有所不同。
程序可能期望 mmap() 始终为映射的段返回相同的基址。在 dbx 下运行会严重影响地址空间,致使 mmap() 返回的地址不可能与在不使用 dbx 运行该程序时所返回的地址相同。要确定这是否构成问题,请查看 mmap() 的所有使用情况,确保返回的地址是程序使用的地址,而非固定编码地址。
如果程序是多线程程序,则它可能包含数据争用或以其他方式依赖线程调度。在 dbx 下运行会干扰线程调度,并可能导致程序以异常顺序执行线程。要检测此类情况,请使用 lock_lint。
否则,请确定使用 adb 或 truss 运行是否会导致相同的问题。
要尽可能减小 dbx 带来的干扰,请尝试当应用程序在其自然环境中运行时与其连接。
以下命令可能会对您的程序进行修改:
assign 命令将 expression 的值赋给 variable。在 dbx 中使用它会永久更改 variable 的值。
assign variable = expression |
弹出当前帧。
弹出 number 个帧。
弹出帧,直至帧号达到指定帧 number。
任何弹出的调用在恢复后将重新执行,这可能导致不必要的程序更改。pop 还为所弹出函数的本地对象调用析构函数。
有关更多信息,请参见pop 命令。
在 dbx 中使用 call 命令时,会调用一个过程,而且该过程将按指定方式执行:
call proc([params]) |
该过程可能会修改程序中的某些内容。dbx 执行该调用的方式好像您已将其写入程序源代码中一样。
有关更多信息,请参见call 命令。
print expression, ... |
如果表达式含有函数调用,则应遵循与使用 call 命令 命令时相同的注意事项。对于 C++,还应注意由重载运算符导致的意外的副作用。
有关更多信息,请参见print 命令。
when event-specification [modifier] {command; ... } |
事件发生时,会执行 command。
到达某行或过程时,便会执行命令。程序的状态是否会更改取决于发出的命令。
有关更多信息,请参见when 命令。
fix |
尽管 fix 命令是一个非常有用的工具,但它会重新编译修改过的源文件,并将修改过的函数动态链接到应用程序中。
确保查看修复并继续的限制。请参见内存泄漏 (mel) 错误。
有关更多信息,请参见fix 命令。
cont at 命令更改运行程序的顺序。如果程序是多线程程序,则要求在 line.id 行继续执行。
cont at line [ id ] |
这可能会更改程序的结果。