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
Posted by: dhqcl | (22) July 15, 2022 12:44 AM
新代码在这里https://github.com/cloudwu/backtrace-mingw
但是编译还没有成功
Posted by: zhaoyun | (21) May 18, 2017 04:10 PM
你好,我用i686-5.3.0-release-win32-dwarf-rt_v4-rev0这个版本的mingw编译的时候,出错,提示backtrace.c:23:17: fatal error: bfd.h: No such file or directory
请问应该怎么解决呀?或者现在有什么新的解决方案吗?
Posted by: Anonymous | (20) June 17, 2016 02:44 PM
哈哈,终于看到回复了。
另外有个小建议就是set的空间分配,开始不用在调用_backtrace之前分配一个节点,全部放到get_bc好了。个人感觉有点怪
Posted by: wosinwu | (19) December 5, 2010 10:42 AM
@wosinwu
已经修正了 :)
Posted by: Cloud | (18) November 29, 2010 11:47 AM
release_set似乎有bug
应该是while(set)吧,不然最后一个节点删不掉
Posted by: wosinwu | (17) November 26, 2010 06:16 PM
前几天的版本有点问题,只能显示 exe 里的栈,如果有额外加载的 dll 就搞不定了。
今天修正了这个问题。
Posted by: Cloud | (16) September 2, 2010 07:20 PM
bfd *b = bfd_openr(procname, 0);
这行总是返回NULL,打印下procname的值,是没问题的。
Posted by: Anonymous | (15) August 23, 2010 04:59 PM
gcc -O2 -shared -Wall -o backtrace.dll backtrace.c -lbfd -liberty -limagehlp -lintl 编译成功,但测试时仍然出现错误,“Failed to init bfd”
Posted by: Anonymous | (14) August 23, 2010 04:39 PM
我更新了 Mingw 版本后发现也缺少 intl 库,现在更新了,在 Makefile 里加上 -lintl 就可以了。
缺少 libintl 的可以去
http://gnuwin32.sourceforge.net/packages/libintl.htm
下载安装 libintl 0.14
Posted by: Cloud | (13) August 19, 2010 05:12 PM
支持!!!
Posted by: jobasic | (12) August 4, 2010 11:08 PM
支持你
Posted by: 夏天 | (11) July 31, 2010 08:47 AM
哈哈,是也
Posted by: qvod | (10) July 29, 2010 09:07 PM
@missdeer
加一个 -lintl 看看。
我的版本的 MinGW 是没有这个库的。
Posted by: Cloud | (9) July 29, 2010 03:26 PM
链接不成功:
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
Posted by: missdeer | (8) July 29, 2010 02:25 PM
http://code.google.com/p/google-breakpad/wiki/GettingStartedWithBreakpad
Google做的开源项目breakpad,可以获得stack traces信息...
Posted by: Anonymous | (7) July 29, 2010 01:18 PM
Only the Microsoft tools use the proprietary PDB format. The GNU tools use STABS or DWARF-2 for the debug information.
Posted by: Cloud | (6) July 29, 2010 11:03 AM
@fseraph
pdb 是 MS 的私有格式,生成 pdb 文件的工具并没有开源。mingw (以及现有的 GNU 工具?) 无法生成 pdb 文件。
Posted by: cloud | (5) July 29, 2010 11:02 AM
如果在windows下收集dump,其实也可以考虑用Windbg提供的脚本为Build脚本加入一个Symbol Store的过程,搭建一个Symbol Server,只要正确的索引PDB文件,用Windbg或者VS打开崩溃之后的dump文件就可以自动获取编译这个版本时的源代码信息,蛮方便的。而且任意版本都可以看。
Posted by: fseraph | (4) July 29, 2010 09:07 AM
好神奇。。。
Posted by: Anonymous | (3) July 28, 2010 10:44 PM
backtrace这种神器一定要顶!
Posted by: halida | (2) July 28, 2010 06:54 PM
内牛满面
Posted by: Anonymous | (1) July 28, 2010 06:53 PM