我目前有一个棘手的bug,它发生在我无法访问源代码或符号的地方,也就是说,我可以看到发生崩溃的指令及其地址,但仅此而已。我想做的是让gdb
在不需要交互的情况下运行,并在运行时显示每条指令,但我还没有找到这样做的方法。
我希望实现的是这样的目标:
(gdb) /* some command */
0x2818a7c0: push %ebp
0x2818a7c1: mov %esp,%ebp
0x2818a7c3: push %ebx
0x2818a7c4: sub $0x4,%esp
...
0x28563622: mov %esi,0x0(%eax)
Program received signal SIGSEGV, Segmentation fault.
我所做的是设置程序计数器的显示,如下所示:
(gdb) display/i $pc
然后使用stepi
运行代码:
(gdb) stepi
1: x/i $pc 0x2818a7c0: push %ebp
然而,崩溃是数百或数千条指令之遥,我希望有一种方法可以看到每一条指令(如果更喜欢的话,可以一起看到),而不必多次点击“enter”。此外,如果我手动操作,我会在每条指令之间看到一个(gdb)
提示符,这是不太理想的。
我曾经简单地研究过scripting,但我唯一的想法是在main()
上设置,让它显示并另一次中断(用于下一条指令),然后继续,但这样我就不能在commands
块中使用commands
,所以它不会像我想象的那样工作。
如果有必要的话,我正在开发FreeBSD。
3条答案
按热度按时间k4ymrczo1#
以下内容应满足您的要求:
但是,这种调试方法很可能是徒劳的:即使在最琐碎的程序中也有太多的指令被执行。
一个更好的方法可能是运行程序直到崩溃,尝试了解当前函数正在做什么以及谁调用了它,并适当地设置断点。
在x86上,即使在完全剥离的可执行文件中,您也经常可以推导出函数边界。
另一件需要查看的事情是
strace/truss
输出,这样就可以看到崩溃点之前的系统调用。iovurdzv2#
Python脚本编写
这将给予比GDB脚本更大的灵活性来实现你疯狂的想法。
这里的主要问题,就像GDB脚本一样,对于大多数没有目标硬件支持的应用程序来说,这可能太慢了,例如:一个C hello世界只需要1分钟就可以处理18 k条指令。
gdb.py
GitHub上游。
主.S
GitHub upstream。
组装和运行:
输出量:
QEMU仿真
编辑:
-d in_asm
只显示翻译块,所以如果一个块被执行多次,它不会显示多次。有一些额外的标志使它更准确,请参见:qemu跟踪哪些指令?QEMU的exec_tb
跟踪后端可能会跟踪这些指令:如何使用QEMU的简单跟踪后端?这比GDB python解决方案的执行速度要快得多,C hello works可以即时运行!但是,日志只有10 k条指令长,而不是同一个可执行文件上的18 k条指令长,所以它必须跳过一些通常会运行的内容。
例如,在用户模式模拟中:
输出量:
另请参阅。
在Ubuntu 18.10、GDB 8.2和QEMU 2.12.0中进行了测试。
ux6nzvsh3#
1.分别反汇编二进制文件(例如,使用objdump),并在调试时查阅清单
1.使用IDA和它的调试器。更好地体验IMO。
(免责声明:我为Hex-Ray工作)