GDB条件中断函数参数

Nic*_*k.D 13 c gdb

我想在函数参数上设置断点,如果它大于某个值.下面的虚拟代码:

int main(void)
{
    uint64_t num = 123456;
    uint64_t x   = 847534;

    uint64_t other = (num*x) - (x/num);

    .... other stuff here (multithreaded stuff)

    calc(other);
}

void calc(uint64_t size)
{
    ...do some stuff with size
}
Run Code Online (Sandbox Code Playgroud)

我试图通过以下方式设置断点:

(gdb) b calc if size == 852479
Run Code Online (Sandbox Code Playgroud)

但它不知道大小是什么,因为它是我猜的参数.如果参数等于某个数字,我将如何中断.打破对此函数的所有调用都不是一个选项,因为它在多线程环境中被调用了十亿次.

bph*_*bph 6

gdb提示:

break "file.c":100 if (size=852479)
Run Code Online (Sandbox Code Playgroud)

或者

break "file.c":100 if (size>852479)
Run Code Online (Sandbox Code Playgroud)

在这里,我假设您想要第 100 行的条件断点,并且您的 src 文件是 file.c

即,如果您想在调用 的线路上中断calc,那么这将是第 100 行 - 根据需要进行修改(您还必须替换sizeother在这种情况下,)

如果您使用的是行号。那是calc函数中的第一个语句之一,那么你会坚持size


Grz*_*ski 5

假设GNU/Linux平台上的x86-64调用约定,您可以%rdi直接检查(64位)寄存器以检查函数的第一个参数:

b calc if $rdi == 852479
Run Code Online (Sandbox Code Playgroud)

这样calc即使您没有加载调试符号也可以中断功能(因此没有代码列表,即通过list calc).

请注意,如果通过优化编译器来内联函数,则此方法将失败.


WGH*_*WGH 5

如果break foo if arg1 == 14由于某种原因不起作用(我遇到过一些函数/二进制文件可以工作,也可以不工作),您可以尝试将其替换为commands.

commands允许您设置一些在每次命中断点时运行的 gdb 命令。要达到所需的效果 - 条件断点 - 您可以执行以下操作:

(gdb) b foo
Breakpoint 1 at 0x400633: file test.c, line 6.
(gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>if arg1 != 14
 >cont
 >end
>end
Run Code Online (Sandbox Code Playgroud)

仅当 时,执行才会在断点处停止arg1 == 14

唯一的缺点是silent抑制典型的“断点命中”消息。您可以删除silent,但即使commands脚本跳过断点,gdb 也会打印消息,如果经常命中断点,则这是不希望的。

不过,您可以在脚本中添加一些自定义通知command