首页
社区
课程
招聘
调试实战|调试一个由内存分配失败导致的崩溃
发表于: 2023-10-17 19:04 9551

调试实战|调试一个由内存分配失败导致的崩溃

2023-10-17 19:04
9551

前一阵子,朋友开发的 QT 程序遇到了一个崩溃问题,抓了 dump 。我跟着一起分析的。最后发现是由于内存分配失败导致的。

一起来练习一下排查思路吧。

说明: 本文很早就写好了草稿,一直没整理成文,Finally~

拿到转储文件,第一件事就是点击 !analyze -v 超链接,让 windbg 帮忙自动分析。
analyze-v
从输出结果中的 Qt5Core!qBadAlloc+0x1a 可以猜测是内存分配失败导致的问题。

加载好符号文件,输入 k 命令查看调用栈。
view-callstack
显示的调用栈,需要使用 !analyze -v 分析结果中的 .cxr 0x59cba8 切换上下文,然后再执行 k 命令即可查看到有意义的调用栈了。

view-meaningful-callstack

查看栈帧 03 对应的代码,可以发现是在通过 file->readAll() 读取整个文件的内容。
view-frame-03

根据代码逻辑及函数局部变量的值,可以确定要读取的文件大小大概是 288.6MB

相比于之前分析空闲内存空间是否足够的办法(感兴趣的小伙伴儿可以点击 这里 查看),我们可以使用更高级的命令进行查找。命令如下:

!address -f:Free -c:".if ( %3 >= 0n302630400) {.echo %1 %2 %3}"

执行后可以发现,输出结果是空,如果减小 0n3026304000n102630400,可以发现有两条记录。说明命令是有效的,而且进程中已经没有一块空闲地址空间可以满足本次分配请求。

search-free-region-larger-than-0n302630400

如果使用 !address -summary 查看地址空间情况,可以发现空闲空间大小是 1.025GB,占整个内存空间的 51.24%。说明当前程序是一个 32 位的程序。

address-summary

使用 !dh client 查看 client 模块的 PE 文件头信息,可以发现确实是 32 位程序,而且没有开启 Large Address Aware 标志。

view-pe-header-with-dh

不要一次性读取全部文件到内存中

这样修改后,可以处理非常大的文件。但是需要修改代码逻辑,相对复杂。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-10-19 21:38 被编程难编辑 ,原因: 上传图片
收藏
免费 3
支持
分享
最新回复 (4)
雪    币: 23080
活跃值: (3432)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
2
图又挂了,这次感觉是图片没上传成功
2023-10-18 10:00
0
雪    币: 852
活跃值: (9821)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
3
图片挂了
2023-10-18 10:08
0
雪    币: 8519
活跃值: (9122)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
4
KevinsBobo 图又挂了,这次感觉是图片没上传成功[em_78]
感谢版主,已经重新上传了
2023-10-19 21:38
0
雪    币: 8519
活跃值: (9122)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
5
TkBinary 图片挂了[em_85]
感谢大佬提醒,已经重新上传了
2023-10-19 21:38
0
游客
登录 | 注册 方可回帖
返回
//