背景
在有开发环境的机器上,可以调试启动代码,复现问题后,很容易就能定位到问题代码。
但是往往给用户的程序是 Release 版本的 exe ,崩溃后,可能会产生一个 dmp 文件。
问题
![]() | 1 snailya 2023-12-26 08:20:08 +08:00 我不会,我就知道打印日志。 |
![]() | 2 ysc3839 2023-12-26 08:20:50 +08:00 via Android ![]() 用 Visual Studio 打开 dmp 文件 |
![]() | 3 liuguangxuan OP @ysc3839 #2 这个 dmp 文件是 Release 版本产生的,能看到堆栈信息吗? |
![]() | 4 corcre 2023-12-26 08:34:41 +08:00 ![]() 打印日志+1 实在不行让客户给个权限, 你丢个 debug 版本的过去远程调试一下 |
![]() | 5 StubbornHuang 2023-12-26 08:38:49 +08:00 ![]() 日志大法 解决问题 |
![]() | 6 ysc3839 2023-12-26 08:40:36 +08:00 via Android @liuguangxuan 能 |
7 liaixiao 2023-12-26 08:44:24 +08:00 via iPhone ![]() 打印日志 or ,查看 windows 的日志,windows 管理有一个日志功能,会记录程序异常退出的日志。最保险的办法还是自己打印日志 |
![]() | 8 DTCPSS 2023-12-26 08:44:49 +08:00 ![]() Windbg |
9 nevermoreluo 2023-12-26 08:46:01 +08:00 排除 release 编译环境问题,dmp 没法定位到问题代码,就开对应的参数 例如 zi ,降低优化之类的,注意自己到底是 mingw 还是 msvc ,两者不一样,去找下对应的编译器怎么让 dmp 文件有符号链接。 感觉大概率是什么两边配置对不上。 vs 的话就仔细对比 vcproject 文件,两个环境有啥区别,cmake 注意不要关掉 return 空的警告(曾经在某个 gcc 版本上遇到没写 return debug 好的,release 崩了的情况) 最后实在不行,你永远可以相信打印日志。。。先把作业做了,后面有空再折腾 release 的 dump 文件如何获取堆栈问题 |
10 ltmst 2023-12-26 08:47:40 +08:00 ![]() |
11 gleArk 2023-12-26 09:12:08 +08:00 ![]() 会汇编语言吗,x32dbg/x64dbg 反编译,跟踪到崩溃前最后一行汇编码,然后分析这一行代码具体执行了什么 不需要源代码 |
12 GreyWang 2023-12-26 09:15:20 +08:00 ![]() dmp 文件已经包含了出问题时的堆栈信息,你可以用 Windows 自己生成的 dmp 文件,也可以利用 crash_handler 自己生成 dmp 文件。 如果 release 程序是用 Visual Studio 编译的: 1 、打开这个程序的解决方案文件 2 、直接把 dmp 文件拖进去 VS 打开 3 、设置符号目录、包含编译 release 程序时的 pdb 文件,或者动态库文件(如果有自己生成库的话) 4 、点击本地调试、直接跳转到崩溃时的堆栈代码帧 |
13 capella 2023-12-26 09:16:51 +08:00 ![]() 系统里的应用日志 |
![]() | 14 sinx003 2023-12-26 09:25:06 +08:00 ![]() 你是用的 vs studio 开发吧,如果你能复现,可以在 release 模式下,实现 debug 下的打断点。 参考: https://blog.csdn.net/qq_36333986/article/details/103897038 |
15 sloknyyz 2023-12-26 09:30:15 +08:00 用 visual studio 打开 dump ,加载 pdb ,会自动分析并显示崩溃堆栈,这是最简单方便的。 |
![]() | 16 tool2d 2023-12-26 09:44:30 +08:00 |
17 zoe0316 2023-12-26 09:48:52 +08:00 ![]() |
![]() | 18 proxytoworld 2023-12-26 10:05:25 +08:00 release 的 dmp 你载入生成的 pdb 不就行了、 |
![]() | 19 z4none 2023-12-26 10:30:16 +08:00 ![]() 使用 dmp 定位问题应该是最方便的, pdb 文件可以用 symstore 工具管理, 保存了 pdb 文件后,通过配置环境变量 _NT_SYMBOL_PATH 就能让 vs 找到 dmp 相应版本的 pdb 文件 |
![]() | 20 695975931 2023-12-26 10:35:14 +08:00 ![]() 给你推荐一个大佬公众号:一线码农聊技术,底下有他的联系方式。 |
![]() | 21 apie 2023-12-26 11:04:16 +08:00 ![]() ReleaseWithDebugInfo |
![]() | 22 shuax 2023-12-26 11:12:37 +08:00 我会 x64dbg 和 ida 配合使用。 |
23 pzpr 2023-12-26 11:20:09 +08:00 ![]() 我一般用 windbg 分析 dump ,通过崩溃线程和变量值定位到代码后自己复现,看到上面有老哥说 vs studio 也可以用,下次尝试下 |
![]() | 24 ashong 2023-12-26 11:27:29 +08:00 via iPhone ![]() |
![]() | 25 402124773 2023-12-26 11:33:46 +08:00 既然有 dump ,你自己又有 pdb ,那肯定是使用 windbg 啊。可以直接看到最后出错的 stack 。 |
![]() | 26 liuguangxuan OP @snailya #1 已经很厉害了。 |
![]() |
![]() | 28 liuguangxuan OP @corcre #4 就算客户给了权限,debug 版本依赖 mfc100ud.dll 、msvcp100d.dll 等各种后缀带 d 的动态库,也没办法直接运行 debug 版本的 exe 。 |
![]() | 29 liuguangxuan OP @StubbornHuang #5 如果是维护一个比较大型的旧项目,根本不知道在哪里加日志。 |
![]() | 30 liuguangxuan OP @nevermoreluo #9 #5 如果是维护一个比较大型的旧项目,根本不知道在哪里加日志。 |
![]() | 31 liuguangxuan OP @gleArk #11 老哥可否细说一下?反编译 exe ,还是 dmp ?如何查到崩溃前最后一行汇编码?查到了汇编码怎么定位问题代码? |
![]() | 32 liuguangxuan OP @GreyWang #12 老哥,假如这个程序是由自动打包工具编译生成的,不是我生成的,而且我没有编译 release 程序时的 pdb 文件,那么怎么定位问题代码呢? |
![]() | 33 liuguangxuan OP @sloknyyz #15 老哥,我没有 pdb ,exe 是自动打包工具编译生成的。这种情况下如何定位问题呢? |
![]() | 34 liuguangxuan OP @zoe0316 #17 多谢老哥,我去了解一下这个工具。 |
![]() | 35 liuguangxuan OP @proxytoworld #18 老哥,我没有 pdb ,exe 是自动打包工具编译生成的。这种情况下如何定位问题呢? |
![]() | 36 liuguangxuan OP @z4none #19 多谢老哥,我去了解一下。 |
![]() | 37 liuguangxuan OP @shuax #22 老哥牛。 |
![]() | 38 liuguangxuan OP @402124773 #25 老哥,我没有 pdb ,exe 是自动打包工具编译生成的。这种情况下如何定位问题呢? |
39 JerryV2 2023-12-26 14:37:09 +08:00 两个比较靠谱的方式: 1 、使用 winDbg 2 、使用远程调试 |
![]() | 40 liuguangxuan OP @JerryV2 #39 老哥,”使用远程调试“指的是在开发机器上,使用附加进程的方式,附加到客户机器上的 exe 吗? |
![]() | 41 proxytoworld 2023-12-26 15:30:48 +08:00 @liuguangxuan 你是什么语言打包的 exe ,python ? |
![]() | 42 ashong 2023-12-26 15:47:45 +08:00 via iPhone ![]() @liuguangxuan 每次编译生成的 pdb 包含源码信息,如果源码修改后 kb 会找不到正确的对应代码行,保留好版本对应的 pdb 和 git commit 就没问题了 |
43 sloknyyz 2023-12-26 16:09:05 +08:00 ![]() 没 pdb 这个崩溃就算了,别看了。重新编译一次,把 pdb 保留好,把新程序给用户替换,让用户复现,等拿到新 dump 再分析。 |
![]() | 44 liuguangxuan OP @proxytoworld #41 开发语言 C++,打包的是 buildbot 。 |
45 GreyWang 2023-12-26 16:30:45 +08:00 @liuguangxuan 自动打包工具如 Jenkins 是可以指定将 pdb 、dll 文件保存的,找配置同事修改一下打包工具的配置就行了,打包结束后自动将 pdb 文件上传至 ftp 服务器,然后你再去下载下来应对后续的问题分析。 |
![]() | 46 liuguangxuan OP @GreyWang #45 棒,老哥! 有没有 Windows 下 C++的其他调试技巧或者最佳实践,老哥传授一下呀 |
![]() | 47 labubu 2023-12-26 17:58:00 +08:00 ![]() 直接用 vs 打开 dump 文件,然后点本机调试,设置 pdb 和代码路径,可以看到奔溃的具体代码行(和平时调试一样) |
![]() | 48 mmdsun 2023-12-26 19:38:06 +08:00 via iPhone ![]() 什么框架开发的软件?一般都可以加一个全局的异常处理器,兜底没有处理的异常,在那里打印日志就行。 |
49 JerryV2 2023-12-27 08:11:18 +08:00 @liuguangxuan #40 是的,但是客户机上需要先启动 VS 的 Remote Debugger ,如果有防火墙需要开对应的端口,教程有很多,一看就会 |
![]() | 50 liuguangxuan OP @JerryV2 #49 这样是不是需要在客户机上运行 Debug 版本?但是 Debug 版本依赖太多以 d 结尾的 dll ,比如 msvcp100d.dll mfc100d.dll 等,估计要在客户机器上安装完整的开发环境了。 |
51 JerryV2 2023-12-27 08:39:12 +08:00 ![]() @liuguangxuan #50 release 版就可以,如果是带调试信息的就更好了 |
52 jones2000 2023-12-27 12:27:47 +08:00 windbg |
53 GreyWang 2023-12-28 09:18:31 +08:00 ![]() @liuguangxuan 如果你的程序集成了其他的子模块,通过头文件和动态库 dll 或者静态库 lib 的方式编译,可以要到子模块的源码,和子模块的头文件放到一起,如果崩溃发生在子模块里,通过调试 dump 可以直接定位到子模块的源码代码行,不需要再手动搜索一遍源文件来定位崩溃点。 |
![]() | 54 james19820515 2024-08-15 18:46:28 +08:00 有结论了吗? |
![]() | 55 liuguangxuan OP @james19820515 你想知道什么? |