-
-
调试实战|调试一个由内存分配失败导致的崩溃
-
发表于:
2023-10-17 19:04
9622
-
前一阵子,朋友开发的 QT
程序遇到了一个崩溃问题,抓了 dump
。我跟着一起分析的。最后发现是由于内存分配失败导致的。
一起来练习一下排查思路吧。
说明: 本文很早就写好了草稿,一直没整理成文,Finally~
拿到转储文件,第一件事就是点击 !analyze -v
超链接,让 windbg
帮忙自动分析。
从输出结果中的 Qt5Core!qBadAlloc+0x1a
可以猜测是内存分配失败导致的问题。
加载好符号文件,输入 k
命令查看调用栈。
显示的调用栈,需要使用 !analyze -v
分析结果中的 .cxr 0x59cba8
切换上下文,然后再执行 k
命令即可查看到有意义的调用栈了。
查看栈帧 03
对应的代码,可以发现是在通过 file->readAll()
读取整个文件的内容。
根据代码逻辑及函数局部变量的值,可以确定要读取的文件大小大概是 288.6MB
。
相比于之前分析空闲内存空间是否足够的办法(感兴趣的小伙伴儿可以点击 这里 查看),我们可以使用更高级的命令进行查找。命令如下:
!address -f:Free -c:".if ( %3 >= 0n302630400) {.echo %1 %2 %3}"
执行后可以发现,输出结果是空,如果减小 0n302630400
为 0n102630400
,可以发现有两条记录。说明命令是有效的,而且进程中已经没有一块空闲地址空间可以满足本次分配请求。
如果使用 !address -summary
查看地址空间情况,可以发现空闲空间大小是 1.025GB
,占整个内存空间的 51.24%
。说明当前程序是一个 32
位的程序。
使用 !dh client
查看 client
模块的 PE
文件头信息,可以发现确实是 32 位程序,而且没有开启 Large Address Aware
标志。
不要一次性读取全部文件到内存中
这样修改后,可以处理非常大的文件。但是需要修改代码逻辑,相对复杂。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-10-19 21:38
被编程难编辑
,原因: 上传图片