我只是在使用 GDB 进行一些实验并使用寄存器,但是在使用系统调用 gettimeofday() 和寄存器上的观察点时遇到了问题。
首先让我展示一个我在做什么的小例子。
好的,这是我正在使用的代码(非常简单):
#include <stdio.h>
main()
{
int num;
getchar();
num=190320;
printf("value: %d\n", num);
}
好吧,我正在做的只是运行程序(它在 getchar() 函数处停止,直到我按下回车键),然后将程序附加到其他 shell 中的 gdb 会话:
gdb -p <pid>
现在我只需在“rdi”寄存器上添加一个条件观察点,以便在分配变量“num”时检查程序的状态:
(gdb) watch $rdi == 190320
Watchpoint 1: $rdi == 190320
现在继续在 gdb 上执行程序,并在我正在运行程序的另一个 shell 上按 enter,正如您所见,gdb 就像我想要的那样在观察点停止程序。
(gdb) c
Continuing.
Watchpoint 1: $rdi == 190320
好吧,这就是我所期望的版本,一个运行正常的简单应用程序和一个在正确时刻停止的观察点。
好的,现在转到问题本身。
这是我之前使用的相同程序,但不同之处在于我在变量分配之前使用了 gettimeofday():
#include <stdio.h>
#include <sys/time.h>
main()
{
int num;
struct timeval tim;
getchar();
gettimeofday(&tim, NULL); /* <---- Here is !!!*/
num=190320;
printf("value: %d\n", num);
}
现在重复我之前做的相同步骤:
- 在 shell 中运行程序
- 将程序附加到另一个 shell 中的 gdb 会话
-在“rdi”寄存器上设置条件观察点
但是现在当我继续在 gdb 中执行并在程序运行的 shell 中按 enter 时,程序就会卡在 gettimeofday() 函数中。
如果我在 gdb 上按“Ctrl+C”,我可以检查程序是否卡在这个函数中
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00007ffc88b85e3c in gettimeofday ()
现在,如果我禁用观察点并尝试再次继续执行,一切正常,程序结束没有问题(显然观察点被禁用,gdb 不会在我想要的那一刻停止程序)。
(gdb) info breakpoint
Num Type Disp Enb Address What
1 watchpoint keep y $rdi == 190320
(gdb) disable 1
(gdb) c
Continuing.
[Inferior 1 (process 4151) exited with code 016]
所以我可以验证程序卡住的原因是寄存器中设置的观察点......
所以问题是,有人可以解释为什么会这样吗?而且,有什么办法可以解决这个问题,并且程序不会卡在 gettimeofday() 函数中并到达观察点吗?
PD:我知道我可以使用其他方法在变量分配中停止程序,但这只是一个实验,我只想解释为什么会发生这种情况
PD2:对不起我的英语不好,这不是我的重要语言。