背景
在有开发环境的机器上,可以调试启动代码,复现问题后,很容易就能定位到问题代码。
但是往往给用户的程序是 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 1
用 Visual Studio 打开 dmp 文件
|
3
liuguangxuan OP @ysc3839 #2 这个 dmp 文件是 Release 版本产生的,能看到堆栈信息吗?
|
4
corcre 2023-12-26 08:34:41 +08:00 1
打印日志+1
实在不行让客户给个权限, 你丢个 debug 版本的过去远程调试一下 |
5
StubbornHuang 2023-12-26 08:38:49 +08:00 1
日志大法 解决问题
|
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 1
打印日志 or ,查看 windows 的日志,windows 管理有一个日志功能,会记录程序异常退出的日志。最保险的办法还是自己打印日志
|
8
DTCPSS 2023-12-26 08:44:49 +08:00 2
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
gbw1992 2023-12-26 08:47:40 +08:00 1
|
11
gleArk 2023-12-26 09:12:08 +08:00 1
会汇编语言吗,x32dbg/x64dbg 反编译,跟踪到崩溃前最后一行汇编码,然后分析这一行代码具体执行了什么
不需要源代码 |
12
GreyWang 2023-12-26 09:15:20 +08:00 1
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 1
系统里的应用日志
|
14
sinx003 2023-12-26 09:25:06 +08:00 1
你是用的 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 1
|
18
proxytoworld 2023-12-26 10:05:25 +08:00
release 的 dmp 你载入生成的 pdb 不就行了、
|
19
z4none 2023-12-26 10:30:16 +08:00 1
使用 dmp 定位问题应该是最方便的,
pdb 文件可以用 symstore 工具管理, 保存了 pdb 文件后,通过配置环境变量 _NT_SYMBOL_PATH 就能让 vs 找到 dmp 相应版本的 pdb 文件 |
20
695975931 2023-12-26 10:35:14 +08:00 1
给你推荐一个大佬公众号:一线码农聊技术,底下有他的联系方式。
|
21
apie 2023-12-26 11:04:16 +08:00 1
ReleaseWithDebugInfo
|
22
shuax 2023-12-26 11:12:37 +08:00
我会 x64dbg 和 ida 配合使用。
|
23
pzpr 2023-12-26 11:20:09 +08:00 1
我一般用 windbg 分析 dump ,通过崩溃线程和变量值定位到代码后自己复现,看到上面有老哥说 vs studio 也可以用,下次尝试下
|
24
ashong 2023-12-26 11:27:29 +08:00 via iPhone 1
|
25
402124773 2023-12-26 11:33:46 +08:00
既然有 dump ,你自己又有 pdb ,那肯定是使用 windbg 啊。可以直接看到最后出错的 stack 。
|
26
liuguangxuan OP @snailya #1 已经很厉害了。
|
27
liuguangxuan OP |
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 1
@liuguangxuan 每次编译生成的 pdb 包含源码信息,如果源码修改后 kb 会找不到正确的对应代码行,保留好版本对应的 pdb 和 git commit 就没问题了
|
43
sloknyyz 2023-12-26 16:09:05 +08:00 1
没 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
daimiaopeng 2023-12-26 17:58:00 +08:00 1
直接用 vs 打开 dump 文件,然后点本机调试,设置 pdb 和代码路径,可以看到奔溃的具体代码行(和平时调试一样)
|
48
mmdsun 2023-12-26 19:38:06 +08:00 via iPhone 1
什么框架开发的软件?一般都可以加一个全局的异常处理器,兜底没有处理的异常,在那里打印日志就行。
|
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 1
@liuguangxuan #50 release 版就可以,如果是带调试信息的就更好了
|
52
jones2000 2023-12-27 12:27:47 +08:00
windbg
|
53
GreyWang 364 天前 1
@liuguangxuan 如果你的程序集成了其他的子模块,通过头文件和动态库 dll 或者静态库 lib 的方式编译,可以要到子模块的源码,和子模块的头文件放到一起,如果崩溃发生在子模块里,通过调试 dump 可以直接定位到子模块的源码代码行,不需要再手动搜索一遍源文件来定位崩溃点。
|
54
james19820515 132 天前
有结论了吗?
|
55
liuguangxuan OP @james19820515 你想知道什么?
|