有没有办法让我的代码可以在一个内存位置插入断点或监视,这将被gdb尊重? (并且可能在没有附加gdb时没有效果。)
我知道如何在gdb会话中执行诸如gdb命令之类的操作,但对于某些类型的调试,如果你知道我的意思,那么以编程方式执行它会非常方便 - 例如,只有bug在特定情况下发生,不是在调用崩溃例程的前11,024次中的任何一次,或者修改内存位置的第一次43028,503次,因此在例程上设置一个简单的断点或对变量的观察点没有帮助 - 这都是误报。
我主要关心Linux,但对OS X(或Windows,但显然不是gdb)存在类似的解决方案感到好奇。
答案 0 :(得分:3)
对于断点,在x86上,您可以使用
在任何位置中断asm("int3");
不幸的是,我不知道如何检测你是否在gdb中运行(在调试器外部执行该操作会使用SIGTRAP信号终止你的程序)
答案 1 :(得分:2)
GDB支持脚本语言,可以在这种情况下提供帮助。例如,您可以在断点上触发一些自定义脚本(例如)可能决定“继续”,因为某些条件尚未满足。
答案 2 :(得分:2)
与您的问题没有直接关系,但可能会有所帮助。你有没有看过execinfo.h中的backtrace和backtrace_symbol调用
http://linux.die.net/man/3/backtrace
这可以帮助您在满足条件时记录回溯。它不是gdb,因此您不能破坏并逐步执行您的程序,但可能有助于快速诊断。
答案 3 :(得分:2)
常用的方法是使用具有非显而易见名称的虚拟函数。然后,您可以扩充.gdbinit或使用其他任何技术来始终打破该符号名称。
琐碎的虚拟功能:
void my_dummy_breakpoint_loc(void) {}
正在测试的代码(可以是类似断言的宏):
if (rare_condition)
my_dummy_breakpoint_loc();
gdb session(显而易见,是吗?):
b my_dummy_breakpoint_loc
确保" my_dummy_breakpoint_loc"非常重要。编译器没有对此技术进行优化。
在最高级的情况下,调用my_dummy_breakpoint_loc的实际汇编程序指令可以替换为" nops"并在运行时通过一些代码自我修改逐站点启用。 Linux内核开发工具使用这种技术来举个例子。