当我们调试一个较复杂问题时,比较难以定位问题,需要尝试多次设置断点,多次 continue,多次查看变 量值等,有时,需要设置一些特殊的调试变量等等。这个过程,往往需要多次重启调试器,也重新开始这些调 试命令。如果调试不支持反向调试,或是反向调试性能较差时,历史记录与调试脚本的配合使用将简化这样的 过程,下面以 zOS USS DBX 为例,我们一起来看看如何使用。同时,这样的调试脚本将有会成为自己或其他 初次使用 dbx 用户的参考。
当我们在调试一个较为复杂的问 题时,可能会比较难以定位,需要尝试多次的设置断点,多次的continue,多次的查看变量值等操作。有时, 还需要设置一些特殊的调试变量。这个过程往往需要多次重启调试器,一遍又一遍的执行这些调试命令。这时 ,如果调试器不支持反向调试,或是反向调试性能较差时,上面的过程就沦落为一系列繁琐,重复性的操作。 手酸了吧,敲累了吧,蒙圈了吧,下面给大家介绍一种利用历史记录与调试脚本相互配合的方法来解放我们可 怜的双手和大脑。以 zOS USS DBX 为例,我们一起来看看我们的操作将怎样得以简化。同时,这种方法对于 未来类似的调试工作或者初次使用 dbx 的用户也具有参考价值。
1. 我们以用dbx调试main程序为例进 行说明,下面列出的是调试过程,在此期间我们设置了断点和调试变量。在调试的最后,我们用 history 命 令得到所有执行的 dbx subcommands。注意咯,黄色的部分是我敲入的用于调试程序的dbx subcommand,其它 部分是dbx的输出。
dbx main
/u/chenxl/example-dbx >> dbx main # 启动dbx调试main
(dbx64) stop in main # 在main()处设置断点
[1] stop in 'int main(int argc, unsigned char **argv)'
(dbx64) set $listwindow=20 # 将默认显示行数10改为20
(dbx64) set $repeat # 设置repeat,enter后,将重复上次的 dbx subcommand
(dbx64) set $catchbp=1 # 执行next/step过程,如果遇到断点,将触发断点,并停下来
(dbx64) run # 设置好调试变量后,let’s go
[1] stopped in main at line 16 in file "main.c" ($t2)
16 int main(int argc, char *argv[])
(dbx64) list # 显示20行源码
17 {
18 volatile int ti = 0;
19
20 if (argc > 2) {
21 x = atoi(argv[1]);
22 if (argc > 3) {
23 y= atoi(argv [2]);
24 }
25 }
26
27 ti = bbb();
28 for( ti = 0; ti < 50; ti++) {
29 aaa();
30 }
31 if (x == 4) {
32 y = bbb();
33 }
34 else {
35 y = ccc(x,y);
36 }