GDB:将观察点设置到数组中,定义值大小

问题描述 投票:0回答:1

我的程序使用

char heap[]
数组作为堆的表示,它可能包含不同大小的值。对于这个问题,最值得注意的是,
(uint16_t*) &heap[0]
(uint16_t*) &heap[2]
处的值是两个 16 位值。

我希望在第二个值上设置一个观察点,并在达到某个值时中断。在这种情况下,第二个值是一个正在倒计时的计数器,我希望在它达到例如零时中断(但出于当前的测试目的,我使用

9998
)。

这就是我的 C 程序的样子(将其放入

test.c
并使用
gcc -g -o mainh test.c
进行编译)

#include <stdint.h>
#include <stdlib.h>
#define HEAP_SIZE 65536
char heap[HEAP_SIZE];
void proc0();
void proc1();
void proc0()
{ }
void proc1()
{ }
void main()
{
    *(uint16_t *) &heap[0] = (uint16_t) 4;
    proc0();
    exit(0);
}

我的框架生成一个GDB文件来安装一些断点并修改这两个值,GDB毫无问题地接受它们。我遇到的问题是首先安装的观察点永远不会被执行。 (将以下命令放入

commandsh.txt

watch *(uint16_t*) &heap[2]
cond 1 *(uint16_t*) &heap[2] == 9998
commands
set *(uint16_t*) &heap[0] = 50
p *(uint16_t*) &heap[0]
continue
end

break proc0
commands
set *(uint16_t*) &heap[2] = (*(uint16_t*) &heap[2]) - 1
c
end

run
q

断点安装在

main
exit
proc0
,但只有
proc0
与我遇到的问题相关,所以其余的都被省略了。
proc0
断点正确触发并将
(uint16_t *) &heap[2]
处的值从初始
9998
减少到
9999
。但是,观察点及其条件永远不会触发,使第一个值保持不变
4
,而我希望它是
50
。 (通过从 bash 运行
gdb -q -x commandsh.txt mainh
来执行命令)

运行 GDB 时的输出显示观察点永远不会中断,并且不会打印指示的堆地址处的值:

Reading symbols from mainh...
Hardware watchpoint 1: *(uint16_t*) &heap[2]
Breakpoint 2 at 0x1151: file test.c, line 8.

This GDB supports auto-downloading debuginfo from the following URLs:
https://debuginfod.ubuntu.com 
Enable debuginfod for this session? (y or [n]) [answered N; input not from terminal]
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 2, proc0 () at test.c:8
8   { }
[Inferior 1 (process 146113) exited normally]

我怀疑问题与我的语法有关,并尝试将观察点更改为

watch {uint16_t} &heap[2]
cond 1 {uint16_t} &heap[2] == 9998
commands
set {uint16_t} &heap[0] = 50
continue
end

但这并没有改变什么。我做错了什么?

c linux debugging gdb
1个回答
0
投票

问题在于,当正在调试的程序更改值时,观察点会起作用。

当它不是程序时,它们工作,但 GDB 本身正在执行更改(正如这里所发生的那样)。

还有其他类似的“错过观察点”的情况,例如内核写入内存:

int fd = open("/dev/zero", ...);
char buf[1] = 'a';               // set a watchpoint on location of buf[0]
read(fd, buf, 1);                // buf[0] is now changed, but watchpoint doesn't "fire".
© www.soinside.com 2019 - 2024. All rights reserved.