我已经使用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部分的替代工具,或者可以写入用户空间内存的系统调用?
答案 0 :(得分:2)
但是,当地址中的值发生变化时,gdb不会停止
当程序在用户空间中运行时,GDB可以检测到值的时间。它不能(也没有)检测内核所做的更改(例如,read(2)
或mremap(2)
系统调用的结果)。如果有问题的地址是MAP_SHARED
映射的一部分,而其他一些进程修改了内存,GDB也不会停止。
答案 1 :(得分:1)
尝试使用软件观察点。在设置观察点之前,请在GDB中设置can-use-hw-watchpoints 0。这将使GDB在每一步之后检查该内存地址的值。这将是非常缓慢的,但至少你可能会遇到意想不到的修改。
可以将多个虚拟内存地址(可能跨越不同进程/分页结构)映射到同一物理内存地址。根据Employed Russian所说的,我猜测观察点寻找对指定虚拟内存地址的写入,而不是物理内存地址。如果这是真的,它将不会捕获写入映射到相同物理地址的不同虚拟内存地址。