驱动程序是内核程序,通常的一个错误,都可能立即招致蓝屏。很快我也遇到了。
由于调试困难,就想用日志来跟踪,但是写完保存文件的程序后,一调用马上蓝屏。
改代码、查资料,发现可能跟IRQL有关:ZwCreateFile只能在IRQL为PASSIVE_LEVEL调用,而我调用的地方IRQL是DISPATCH_LEVEL。改用线程方式,文件出来了。
高兴没多久,蓝屏再次出现,但现在没那么频繁。于是采用排除法,一点点地注释掉代码,发现哪怕线程没做任何操作,也会蓝屏,但不开线程则一点问题没有。在CSDN问,google查,还是一筹莫展,决定暂时搁置。
继续测试其他功能,一切都还顺利。但后来又出现蓝屏了,Windows 7不到半小时就会出现,但当我用Windows xp测试时,电脑却连续运行了十几小时都没问题。在另一台Windows 7电脑上也没出现过问题。
后来用WinDbg查看蓝屏时生成的dmp文件,报告的出错位置并不固定,有时候甚至报告其他系统文件出错。但有一点可以肯定的是,只要卸载了我的驱动,就不会出现蓝屏,所以还是必需在代码中找问题。
查看了多次dmp文件之后,发现MPSendPackets函数中有一行被报告出错的次数比较多,于是又采用逐渐缩小范围的方式,查找出错位置,最后找到了一个从Packet中获取数据包缓冲区的函数。这个函数从Packet中复制数据包到传入的缓冲区,但没有判断缓冲区大小。马上加上保护措施,再测试,连续两三天都没蓝屏。看来问题解决了。
回过头再看那个函数,调用之前我直接分配了2000字节,按理说一个数据包最大也就1518字节,写了调试信息,发现不仅有超过1518的,最多居然有6736!而且只出现在发送的时候。问题基本确认了,但为何会出现超过1518的包,而且在Windows xp甚至其他版本的Windows 7却不出现,有待进一步研究。
还是我对待测试代码不够严谨啊,本应该根据包大小分配内存的。最后根据Packet->Private.TotalLength来分配缓冲区,测试通过。