0

编辑:我似乎弄错了,回溯在 Linux 上的任何地方都能很好地工作——只有当从 ubuntu 上的 gdb 远程调试到远程窗口时,在 msvcrt 中输入内存分配函数之一后,stacktrace 才会被完全破坏。 . 该死的微软。

这发生在 64 位和 32 位窗口上,所以我不确定这与展开信息有关......

编辑:似乎添加 -g3 和 -Og 有助于解决某些程序中的部分问题,但问题仍然存在于其他程序中,无法在此处发布它们的源代码,因为它是我公司的 IP - 抱歉!

背景

我使用 gcc 编译 ubuntu->ubuntu 和 mingw 编译 ubuntu->windows。

我创建了一个跨平台(linux + windows)内存跟踪和泄漏检测库,它在第一条指令(不是 IAT/PLT 挂钩)上使用程序集字节补丁挂钩 malloc/calloc/realloc/free。

钩子重定向到一个门,该门检查钩子是否在当前线程中启用,如果是,则重定向到内存跟踪钩子函数,否则它只是重定向到实际函数的蹦床,如果它们被该线程禁用。

该库运行良好,可以检测 linux/windows 上的泄漏(可能适用于 mac,但我没有)。

我使用该库以编程方式检测代码中的泄漏,我可以在内存分配例程上安装回调并以编程方式引发断点(通过循环并等待调试器附加然后在回调中执行 asm("int3")),以便我可以在我的程序处于泄漏内存的调用中时附加到它。

一切正常,直到我尝试从回调中查看回溯,我知道这可能是因为展开信息可能不再与我的堆栈匹配,因为我通过插入的钩子例程插入了新的帧和数据。

编辑:如果我误认为展开信息与堆栈不匹配是回溯不正确的原因,请纠正我!

问题

我可以做一些小技巧来欺骗 GDB 从我的钩子回调中正确重建回溯吗?

我知道我可以使用 libdwarf 或其他东西手动行走和编辑展开信息,但我想这会非常麻烦和庞大。

所以我想知道是否有可能我可以做的黑客或作弊来欺骗 GDB 正确重建回溯?

如果没有简单的技巧或技巧,那么我解决此问题的所有选择是什么?

编辑:只是为了清除所有内容的确切调用顺序:

program
   V
malloc
   V
hook_malloc -> hooks are disabled -> return malloc trampoline -> real malloc > program
   V
hooks are enabled 
   V
Call original malloc -> malloc trampoline -> real malloc -> returns to hook
   V
Record memory size/info etc from malloc
   V
Call user defined callback -> **User defined callback* -> returns to hook
   V
return to program

这是我要捕获回溯的“用户定义的回调”

4

1 回答 1

-1

显然这是同一个问题GDB Windows ?? 在回溯中

解决方案是简单地将 -g3 添加到 mingw 编译标志和 viola 我有完整的回溯!

编辑:没关系,这不是全部答案。似乎此修复程序适用于某些测试程序,但其他程序似乎仍然显示不正确的回溯,例如:

(gdb) bt
#0  malloc_callback (s=38, rv=0x2c5058) at test_dll.c:729
#1  0x000000000040731d in hook_malloc_raw (file=0x410ea1 <__FUNCTION__.63079+55> "", function=0x410ea1 <__FUNCTION__.63079+55> "", line=0, s=38, rv=8791758343065)
#2  0x0000000000407367 in hook_malloc (s=38)
#3  0x000007fefda20b9e in ?? ()
#4  0x0000000000000026 in ?? ()
#5  0x0000000000410ea1 in __FUNCTION__.63079 ()
#6  0x0000000000000000 in ?? ()

显然第 4 帧实际上不是堆栈帧,我不确定为什么第 5 帧被标记为“__FUNCTION__.63079”。

Edit2:如果人们要对此投反对票,至少发表评论说明原因

于 2018-11-09T22:02:18.290 回答