6

请教各位老哥, Windows 下 Release 程序崩溃,应该如何定位问题?

 8 months ago
source link: https://www.v2ex.com/t/1003397
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Windows

请教各位老哥, Windows 下 Release 程序崩溃,应该如何定位问题?

  liuguangxuan · 21 小时 44 分钟前 · 2032 次点击

背景

在有开发环境的机器上,可以调试启动代码,复现问题后,很容易就能定位到问题代码。

但是往往给用户的程序是 Release 版本的 exe ,崩溃后,可能会产生一个 dmp 文件。

问题

  1. 这个 dmp 文件是 Release 版本 exe 产生的,如何根据这个 dmp 定位到问题代码?
  2. 如果不能根据这个 dmp 文件定位到问题代码,那么是否有其他方式,定位问题代码?
  3. 是否有定位问题,调试 bug 的其他技巧?
  4. 关于调试符号( pdb 文件),了解到有符号服务器,可以专门存储符号文件,是否有相关的最佳实践?如何编译,打包,发布,存储符号,调试定位问题?
48 条回复    2023-12-26 19:38:06 +08:00
snailya

snailya      21 小时 36 分钟前

我不会,我就知道打印日志。
ysc3839

ysc3839      21 小时 36 分钟前 via Android   ❤️ 1

用 Visual Studio 打开 dmp 文件
liuguangxuan

liuguangxuan      21 小时 32 分钟前

@ysc3839 #2 这个 dmp 文件是 Release 版本产生的,能看到堆栈信息吗?
corcre

corcre      21 小时 22 分钟前   ❤️ 1

打印日志+1
实在不行让客户给个权限, 你丢个 debug 版本的过去远程调试一下
StubbornHuang

StubbornHuang      21 小时 18 分钟前   ❤️ 1

日志大法 解决问题
ysc3839

ysc3839      21 小时 16 分钟前 via Android

liaixiao

liaixiao      21 小时 12 分钟前 via iPhone   ❤️ 1

打印日志 or ,查看 windows 的日志,windows 管理有一个日志功能,会记录程序异常退出的日志。最保险的办法还是自己打印日志
DTCPSS

DTCPSS      21 小时 12 分钟前   ❤️ 2

Windbg
nevermoreluo

nevermoreluo      21 小时 10 分钟前

排除 release 编译环境问题,dmp 没法定位到问题代码,就开对应的参数 例如 zi ,降低优化之类的,注意自己到底是 mingw 还是 msvc ,两者不一样,去找下对应的编译器怎么让 dmp 文件有符号链接。
感觉大概率是什么两边配置对不上。
vs 的话就仔细对比 vcproject 文件,两个环境有啥区别,cmake 注意不要关掉 return 空的警告(曾经在某个 gcc 版本上遇到没写 return debug 好的,release 崩了的情况)

最后实在不行,你永远可以相信打印日志。。。先把作业做了,后面有空再折腾 release 的 dump 文件如何获取堆栈问题
gleArk

gleArk      20 小时 44 分钟前   ❤️ 1

会汇编语言吗,x32dbg/x64dbg 反编译,跟踪到崩溃前最后一行汇编码,然后分析这一行代码具体执行了什么
不需要源代码
GreyWang

GreyWang      20 小时 41 分钟前   ❤️ 1

dmp 文件已经包含了出问题时的堆栈信息,你可以用 Windows 自己生成的 dmp 文件,也可以利用 crash_handler 自己生成 dmp 文件。

如果 release 程序是用 Visual Studio 编译的:
1 、打开这个程序的解决方案文件
2 、直接把 dmp 文件拖进去 VS 打开
3 、设置符号目录、包含编译 release 程序时的 pdb 文件,或者动态库文件(如果有自己生成库的话)
4 、点击本地调试、直接跳转到崩溃时的堆栈代码帧
capella

capella      20 小时 40 分钟前   ❤️ 1

系统里的应用日志
sloknyyz

sloknyyz      20 小时 26 分钟前

用 visual studio 打开 dump ,加载 pdb ,会自动分析并显示崩溃堆栈,这是最简单方便的。
tool2d

tool2d      20 小时 12 分钟前

@nevermoreluo mingw 现在和以前不一样,只要配置一下,就可以生成 vc 能识别 codeview 调试信息。

也就是说,vc 能直接调试任何 exe 代码了。
zoe0316

zoe0316      20 小时 7 分钟前   ❤️ 1

也可以试试集成 Breakpad 到项目里,根据 pdb 生成符号表,crash 的时候再解析 dmp 。

https://github.com/google/breakpad
proxytoworld

proxytoworld      19 小时 51 分钟前

release 的 dmp 你载入生成的 pdb 不就行了、
z4none

z4none      19 小时 26 分钟前   ❤️ 1

使用 dmp 定位问题应该是最方便的,
pdb 文件可以用 symstore 工具管理,
保存了 pdb 文件后,通过配置环境变量 _NT_SYMBOL_PATH 就能让 vs 找到 dmp 相应版本的 pdb 文件
695975931

695975931      19 小时 21 分钟前   ❤️ 1

给你推荐一个大佬公众号:一线码农聊技术,底下有他的联系方式。
apie

apie      18 小时 52 分钟前   ❤️ 1

ReleaseWithDebugInfo
shuax

shuax      18 小时 44 分钟前

我会 x64dbg 和 ida 配合使用。
pzpr

pzpr      18 小时 36 分钟前   ❤️ 1

我一般用 windbg 分析 dump ,通过崩溃线程和变量值定位到代码后自己复现,看到上面有老哥说 vs studio 也可以用,下次尝试下
ashong

ashong      18 小时 29 分钟前 via iPhone   ❤️ 1

@liuguangxuan 可以,如果你编译的时候生成 debug info , 记得保留好 pdb 以及源代码状态。

用 vs 或者 windbg 都可定位
402124773

402124773      18 小时 23 分钟前

既然有 dump ,你自己又有 pdb ,那肯定是使用 windbg 啊。可以直接看到最后出错的 stack 。
liuguangxuan

liuguangxuan      16 小时 47 分钟前

@snailya #1 已经很厉害了。
liuguangxuan

liuguangxuan      16 小时 43 分钟前

@ashong #24 老哥可否细说一下”保留好 pdb 以及源代码状态“?
pdb 我看楼下有提到了 symstore ,是这个吗?
源代码状态,git 版本回退回来是否可以?
liuguangxuan

liuguangxuan      16 小时 42 分钟前

@corcre #4 就算客户给了权限,debug 版本依赖 mfc100ud.dll 、msvcp100d.dll 等各种后缀带 d 的动态库,也没办法直接运行 debug 版本的 exe 。
liuguangxuan

liuguangxuan      16 小时 41 分钟前

@StubbornHuang #5 如果是维护一个比较大型的旧项目,根本不知道在哪里加日志。😂
liuguangxuan

liuguangxuan      16 小时 39 分钟前

@nevermoreluo #9 #5 如果是维护一个比较大型的旧项目,根本不知道在哪里加日志。😂
liuguangxuan

liuguangxuan      16 小时 38 分钟前

@gleArk #11 老哥可否细说一下?反编译 exe ,还是 dmp ?如何查到崩溃前最后一行汇编码?查到了汇编码怎么定位问题代码?
liuguangxuan

liuguangxuan      16 小时 34 分钟前

@GreyWang #12 老哥,假如这个程序是由自动打包工具编译生成的,不是我生成的,而且我没有编译 release 程序时的 pdb 文件,那么怎么定位问题代码呢?
liuguangxuan

liuguangxuan      16 小时 32 分钟前

@sloknyyz #15 老哥,我没有 pdb ,exe 是自动打包工具编译生成的。这种情况下如何定位问题呢?
liuguangxuan

liuguangxuan      16 小时 30 分钟前

@zoe0316 #17 多谢老哥,我去了解一下这个工具。
liuguangxuan

liuguangxuan      16 小时 30 分钟前

@proxytoworld #18 老哥,我没有 pdb ,exe 是自动打包工具编译生成的。这种情况下如何定位问题呢?
liuguangxuan

liuguangxuan      16 小时 29 分钟前

@z4none #19 多谢老哥,我去了解一下。
liuguangxuan

liuguangxuan      16 小时 28 分钟前

@shuax #22 老哥牛。
liuguangxuan

liuguangxuan      16 小时 27 分钟前

@402124773 #25 老哥,我没有 pdb ,exe 是自动打包工具编译生成的。这种情况下如何定位问题呢?
JerryV2

JerryV2      15 小时 19 分钟前

两个比较靠谱的方式:

1 、使用 winDbg

2 、使用远程调试
liuguangxuan

liuguangxuan      14 小时 27 分钟前

@JerryV2 #39 老哥,”使用远程调试“指的是在开发机器上,使用附加进程的方式,附加到客户机器上的 exe 吗?
proxytoworld

proxytoworld      14 小时 26 分钟前

@liuguangxuan 你是什么语言打包的 exe ,python ?
ashong

ashong      14 小时 9 分钟前 via iPhone   ❤️ 1

@liuguangxuan 每次编译生成的 pdb 包含源码信息,如果源码修改后 kb 会找不到正确的对应代码行,保留好版本对应的 pdb 和 git commit 就没问题了
sloknyyz

sloknyyz      13 小时 47 分钟前   ❤️ 1

没 pdb 这个崩溃就算了,别看了。重新编译一次,把 pdb 保留好,把新程序给用户替换,让用户复现,等拿到新 dump 再分析。
liuguangxuan

liuguangxuan      13 小时 47 分钟前

@proxytoworld #41 开发语言 C++,打包的是 buildbot 。
GreyWang

GreyWang      13 小时 26 分钟前

@liuguangxuan 自动打包工具如 Jenkins 是可以指定将 pdb 、dll 文件保存的,找配置同事修改一下打包工具的配置就行了,打包结束后自动将 pdb 文件上传至 ftp 服务器,然后你再去下载下来应对后续的问题分析。
liuguangxuan

liuguangxuan      13 小时 21 分钟前

@GreyWang #45 棒,老哥!
有没有 Windows 下 C++的其他调试技巧或者最佳实践,老哥传授一下呀😁
daimiaopeng

daimiaopeng      11 小时 58 分钟前

直接用 vs 打开 dump 文件,然后点本机调试,设置 pdb 和代码路径,可以看到奔溃的具体代码行(和平时调试一样)
mmdsun

mmdsun      10 小时 18 分钟前 via iPhone

什么框架开发的软件?一般都可以加一个全局的异常处理器,兜底没有处理的异常,在那里打印日志就行。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK