背景
有一个以前的老客户,他在开发avstream的麦克风驱动,最近上线,但是客户那边时不时报出蓝屏问题,他们工程师查了很久,就是找不到头绪,只能靠瞎猜,改了很多次问题还是依旧,客户已经不耐烦了,毕竟是蓝屏问题,影响还是很大的,于是他们求助到了我这里。
dump分析
首先我还是看蓝屏dump,信息如下:
可以看到arg1和arg4是一样的,拿到他们的pdb和代码一看,在如下函数的入口处就挂了。
调用该函数的地方:
先看下CAudioCaptureFilter::TimerDpc的反汇编,是可以正常反编译出来的,证明地址不是无效的地址。
从上面蓝屏信息我们可以看到,IRQL是2,该原因有两个:
(1)在DISPATCH_LEVEL的IRQL上访问分页内存
(2)在DISPATCH_LEVEL的IRQL上访问无效地址
我们已经排除了地址是无效地址,那只能是无效内存了,但这是个函数,是个可执行的地址,该可执行地址难道分页了?于是仔细检查代码,发现代码段部分存在这样的修饰:
这代表该函数放在可分页的代码段,但是该函数被调用的地方是定时器的回调,是个DISPATCH_LEVEL的IRQL,导致分页的时候蓝屏了。
解决方案
(1)删除代码的可分页修饰,增加该修饰主要是优化代码,不必将所有的代码都放在非分页内存上,所以删除就可以了。
(2)如果为了优化代码,保留代码的可分页修饰,但是切记该代码被调用该的地方一定要在PASSIVE_LEVEL下,一些需要在DISPATCH_LEVEL下运行的代码一定要放在如下修饰的下面: