Crush The Crash--dump和异常


这篇文章里聊一些crash dump相关的东西,dump和exception两者在查看dump的时候常常是相关出现的。

对两者有必要的了解,会让问题处理事半功倍。

dump简介

就是程序在crash的时候,会存下来的dump文件,这里有两种:

  • 不带heap信息的dump文件:叫minidump,只有stack上的信息以及register信息,size比较小, 适合游戏上线之后崩溃的时候,统一发到bug服务器来供开发团队处理
    • 由于函数调用的参数是放在stack上的,所以一般函数的参数信息是全的(但是也遇到过不准的)
    • 还有程序里各种module的信息
  • 带heap信息的dump文件:一般叫fulldump,标准说法是minidump with heap,除了stack上的信息,还有heap内存上的信息,dump文件往往很大,对于大型游戏来说,超过1g是经常的
    • 信息很全,很多时候minidump处理不了的bug,有了一发fulldump,真是雪中送炭,直接击杀bug
大部分游戏里处理crash dump收集是一个公共组来做的,比如腾讯这样的公司,更是有不止一个团队来做这个事情。
这也导致开发团队因为不需要处理这块事情,而不太清楚这块还能做一些什么事情,实践下来,在自己游戏里添加能够存下fulldump的机制是非常重要的。

存fulldump
MiniDumpWriteDump 这个函数的DumpType 参数使用MiniDumpWithFullMemory就好
然后指定游戏在某些情况下,比如内网同事测试,比如游戏目录下放某些特殊文件的时候,存下fulldump就好

存dump与异常
这里聊下实际游戏中怎么存dump下来,一般是在游戏crash的时候,来存dump然后发到bug服务器上。
这个crash一般是由windows处理异常的机制来捕捉和处理的。

异常捕捉
这个机制就是SEH(structured exception handling),它和常规的c++异常捕捉还不太一样,常规c++是捕捉抛出的异常,SEH则是可能在各种情况下启用。
在最常出现的crash--Exception code: C0000005 ACCESS_VIOLATION,出现非法地址访问的时候,就会出现异常,然后就开始进入到SEH的异常处理过程中。

异常处理
对于异常处理,会有若干exception handler,程序自己也可以注册一些exception handler,在出现会导致程序崩溃的异常的时候,自己的handler里面就可以存dump,然后发出bug信息包了。
调用这个exception handler的时候,如果使用windbg来看的话,会看
ntdll!RtlDispatchException+0x45a
这样的callstack,在这个函数里就是去转发给handler来处理,一定情况下,在处理的过程中会继续crash,那就酷炫了。。。

visual studio中查看dump
一般直接通过visual studio就能查看dump,把symbol path设置好,就能看到相关的代码了。

stack截取
这里一般会有一个stack的截取,也就是在vs中看dump的时候,看到的是发生异常的地方,在开始dispatch exception的地方,就截取了。
这个在绝大多数的时候是ok的,但是我们需要知道有这么个事情,就是发生异常了(比如非法地址访问),程序里其实还处理了很多事情,vs中我们也只是看到一部分(最有帮助的部分)。一些情况下,比如由于内存耗尽情况下的crash,会在exception handler里面由于内存不足,知道这样的处理方式会对我们处理问题很有帮助。

常用信息
dump里面各种信息还是比较全的,比如crash在哪个thread里,在哪个module里都会有。
处理中一个比较奇怪的是:我们在内部一些组件会出现module overlap的情况,也就是一个dll使用的地址和我们游戏exe的地址范围一部分是重复的。
这个时候vs解析的时候,会默认认为stack是我们游戏的,但是callstack完全是不合理的(不会出现这样的函数调用),这个时候的处理是看寄存器EIP(存放代码指令地址的寄存器),发现这个代码段是处于module overlap的范围内的,进而定位到是另外一个dll的问题。
module在vs里面专门有一个view,地址也可以看到:


windbg中查看dump
唔,这个话题其实很大,windbg功能比vs在看dump方面强大太多,功能也非常的强力,使用起来也更麻烦一些,后面看看专门开一个blog吧,这里就是说下,windbg可以作为看dump的后台大哥,必要时候请出来清场。。。

为了在Windows上安装ADB工具,你可以按照以下步骤进行操作: 1. 首先,下载ADB工具包并解压缩到你自定义的安装目录。你可以选择将其解压缩到任何你喜欢的位置。 2. 打开运行窗口,可以通过按下Win+R键来快速打开。在运行窗口中输入"sysdm.cpl"并按下回车键。 3. 在系统属性窗口中,选择"高级"选项卡,然后点击"环境变量"按钮。 4. 在环境变量窗口中,选择"系统变量"部分,并找到名为"Path"的变量。点击"编辑"按钮。 5. 在编辑环境变量窗口中,点击"新建"按钮,并将ADB工具的安装路径添加到新建的路径中。确保路径正确无误后,点击"确定"按钮。 6. 返回到桌面,打开命令提示符窗口。你可以通过按下Win+R键,然后输入"cmd"并按下回车键来快速打开命令提示符窗口。 7. 在命令提示符窗口中,输入"adb version"命令来验证ADB工具是否成功安装。如果显示版本信息,则表示安装成功。 这样,你就成功在Windows上安装了ADB工具。你可以使用ADB工具来执行各种操作,如枚举设备、进入/退出ADB终端、文件传输、运行命令、查看系统日志等。具体的操作方法可以参考ADB工具的官方文档或其他相关教程。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [windows环境安装adb驱动](https://blog.csdn.net/zx54633089/article/details/128533343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Windows下安装使用ADB,简单易懂教程](https://blog.csdn.net/m0_37777700/article/details/129836351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值