2

我已经用 gdb 调试了 QEMU。

为了跟踪意外的内存访问,我在特定地址设置了一个硬件观察点。但是,当地址中的值更改时,gdb 不会停止。这是我第一次在 gdb 中使用硬件观察点功能。

我不知道为什么会这样,并想解决这个问题。

以下是 gdb 控制台输出。

$ gdb --args ./qemu-system-x86_64 -m 512 -hda linux-0.2.img 

...

(gdb) x 0x7fffbbe8e000
0x7fffbbe8e000: 0x00000000
(gdb) watch *(int *)0x7fffbbe8e000
Hardware watchpoint 1: *(int *)0x7fffbbe8e000
(gdb) c
Continuing.
[Thread 0x7fffc2dad700 (LWP 3162) exited]
[New Thread 0x7fffc2dad700 (LWP 3169)]
[Thread 0x7fffc2dad700 (LWP 3169) exited]
[New Thread 0x7fffc2dad700 (LWP 3173)]
qemu: /home/nutsman/git_repo/M-QEMU/qemu-2.3.1/exec.c:3007:      ldl_phys_internal: Assertion `val1 == val' failed. 

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffc23ca700 (LWP 3163)]
0x00007ffff61f4cc9 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: no such a file or directory

(gdb) x 0x7fffbbe8e000
0x7fffbbe8e000: 0x6c7cebfa

谢谢你,受雇的俄罗斯人。内存是用户空间并使用 MAP_PRIVATE 分配的,因此任何其他程序都不能更改它的内容。您能否告诉我替代工具来查找 QEMU 中更改值的部分,或者可以写入用户空间内存的系统调用?

4

2 回答 2

2

但是,地址中的值更改时 gdb 不会停止

当程序在用户空间运行时,GDB 可以检测到值何时发生变化。它不能(也不会)检测内核所做的更改(例如,作为系统调用的结果read(2)mremap(2)。如果有问题的地址是MAP_SHARED映射的一部分,并且其他一些进程修改了内存,GDB 也不会停止。

于 2016-03-28T04:26:12.390 回答
1

尝试使用软件观察点。在设置观察点之前,请在 GDB 中设置 can-use-hw-watchpoints 0。这将使 GDB 在每一步之后检查该内存地址的值。这将非常缓慢,但至少您可能会发现意外的修改。

可以将多个虚拟内存地址(可能跨不同的进程/分页结构)映射到相同的物理内存地址。根据 Employed Russian 所说的,我猜测观察点寻找对指定虚拟内存地址的写入,而不是物理内存地址。如果这是真的,它不会捕获对映射到相同物理地址的不同虚拟内存地址的写入。

于 2016-04-13T16:38:06.693 回答