« 换了个新手机 | 返回首页 | Windows 下调试问题一则 »

mingw 下的 stack backtrace

我们的项目的 Windows 版本是用 MinGW 开发的。当程序在 Windows 下挂掉后,固然可以用 gdb 调试,看到调用栈。但有些时候还是不够方便。

比如说今天,我们写的模型编辑器发到广州美术同事使用时,就出了问题。3d 程序在不同显卡环境下的确容易出故障,异地调试程序非常困难。这个时候,多么想看看调用栈啊。

The GNU C Library 是提供了 Backtraces 的,可惜 MinGW 不支持 :( 。最后打算自己写一个。

获取 stack backtrace 调试信息的基本原理就是利用 windows 的 imagehlp.dll 取得正在运行的 exe 或 dll 被系统加载到内存后的镜像信息(可能被重定位了)。然后利用 libbfd 按偏移量取得源码的相关信息。

在崩溃时获取调用栈信息使用的是 SetUnhandledExceptionFilter ,可以注册一个函数拿到 context 继续处理。

搜索一番后,发现其实有个哥们实现了个 C++ 版本 。不过我还是用我自己写的 C 版本吧。

使用非常简单,只需要把事先编译好的 backtrace.dll 在需要追踪的程序前面加载一下即可,然后在 crash 时就会向 strerr 输出详细的堆栈信息。

有兴趣的同学可以看这里:我把它在 code.google.com 上开源了

Comments

不需要-lintl也能编译backtrace64.dll成功,那-lintl有什么作用?对这个的确不了解. 另外,exception_filter中的函数调用非常严格,在这里调用SymInitialize失败概率较高.应该改成主程序负责SymInitialize和SymCleanup
新代码在这里https://github.com/cloudwu/backtrace-mingw 但是编译还没有成功
你好,我用i686-5.3.0-release-win32-dwarf-rt_v4-rev0这个版本的mingw编译的时候,出错,提示backtrace.c:23:17: fatal error: bfd.h: No such file or directory 请问应该怎么解决呀?或者现在有什么新的解决方案吗?
哈哈,终于看到回复了。 另外有个小建议就是set的空间分配,开始不用在调用_backtrace之前分配一个节点,全部放到get_bc好了。个人感觉有点怪
@wosinwu 已经修正了 :)
release_set似乎有bug 应该是while(set)吧,不然最后一个节点删不掉
前几天的版本有点问题,只能显示 exe 里的栈,如果有额外加载的 dll 就搞不定了。 今天修正了这个问题。
bfd *b = bfd_openr(procname, 0); 这行总是返回NULL,打印下procname的值,是没问题的。
gcc -O2 -shared -Wall -o backtrace.dll backtrace.c -lbfd -liberty -limagehlp -lintl 编译成功,但测试时仍然出现错误,“Failed to init bfd”
我更新了 Mingw 版本后发现也缺少 intl 库,现在更新了,在 Makefile 里加上 -lintl 就可以了。 缺少 libintl 的可以去 http://gnuwin32.sourceforge.net/packages/libintl.htm 下载安装 libintl 0.14
支持!!!
支持你
哈哈,是也
@missdeer 加一个 -lintl 看看。 我的版本的 MinGW 是没有这个库的。
链接不成功: g:/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../libbfd.a(libbfd.o):libbfd.c:(.tex t+0x6ee): undefined reference to `libintl_dgettext' g:/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../libbfd.a(libbfd.o):libbfd.c:(.tex t+0x740): undefined reference to `libintl_dgettext' g:/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../libbfd.a(libbfd.o):libbfd.c:(.tex t+0x79b): undefined reference to `libintl_dgettext' g:/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../libbfd.a(libbfd.o):libbfd.c:(.tex t+0x7d0): undefined reference to `libintl_dgettext' g:/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../libbfd.a(bfd.o):bfd.c:(.text+0x8f d): undefined reference to `libintl_dgettext' g:/mingw/bin/../lib/gcc/mingw32/4.4.0/../../../libbfd.a(bfd.o):bfd.c:(.text+0x96 4): more undefined references to `libintl_dgettext' follow
http://code.google.com/p/google-breakpad/wiki/GettingStartedWithBreakpad Google做的开源项目breakpad,可以获得stack traces信息...
Only the Microsoft tools use the proprietary PDB format. The GNU tools use STABS or DWARF-2 for the debug information.
@fseraph pdb 是 MS 的私有格式,生成 pdb 文件的工具并没有开源。mingw (以及现有的 GNU 工具?) 无法生成 pdb 文件。
如果在windows下收集dump,其实也可以考虑用Windbg提供的脚本为Build脚本加入一个Symbol Store的过程,搭建一个Symbol Server,只要正确的索引PDB文件,用Windbg或者VS打开崩溃之后的dump文件就可以自动获取编译这个版本时的源代码信息,蛮方便的。而且任意版本都可以看。
好神奇。。。
backtrace这种神器一定要顶!
内牛满面

Post a comment

非这个主题相关的留言请到:留言本