遇到"Unhandled exception in app.exe (QTGUID4.DLL): 0xC0000005: Access Violation"错误的解决过程
起因:
前几天,在没有稳定版本的基础上增加了一个功能,结果程序经常无情的崩溃了。
现象:调试的时候崩溃,提示“Unhandled exception in app.exe (QTGUID4.DLL): 0xC0000005: Access Violation”,会调到Label的setEnabled处;
屏蔽掉相关代码之后,再次运行,会跳到Button的setPalette处;
屏蔽掉相关代码之后,再次运行,又会调到Label的setText处;
屏蔽掉相关代码之后,再次运行,会跳到一个vector变量的at(i)处。
这个屏蔽了之后就可以了。
release的时候,不固定的崩溃,日志报告为常见的debug信息:
Warning: Qt has caught an exception thrown from an event handler.
Throwing exceptions from an event handler is not supported in Qt.
You must reimplement QApplication::notify() and catch all exception there.
经常性的,虽然时间不固定,但是很容易重新(想不重现都不行)。
如果使用try()catch(...)来讲问题代码封闭,调试时会崩溃到Qt内核。
想上网上找找吧,错误不明显,网速也慢的难受,只好自己闷骚了。
想来想去,大概有这么几个会导致崩溃的地方:
1、使用了不当的指针,导致系统变量乱套了。不过也不太可能,一个变量乱套可以,总不至于A、B、C、D都乱套吧。
2、系统使用了QTimer定时器,但是使用了长时间的延时。有可能阻碍主线程或串口线程动作,阻碍主线程解析串口数据缓冲区溢出,导致崩溃。
3、系统结果需要定时保存到本地Excel文件。可能是Excel模块出一些不太严重的问题,时间长了导致系统随机崩溃。
4、或者别人安装、卸载了什么软件,导致操作系统环境变化,影响了调试、运行环境,最终导致崩溃。
5、或者Qt本身环境不稳定。想想,也不太可能吧,毕竟已经十几年了,一般的应用应该没问题。要是真有问题,那真的恭喜我了。
稳定版本与现在的区别:
1、延时是200ms,现在的是4000ms。
2、增加了平均值输出功能,并引入了平均值数据存储变量(数组)。
3、界面有原来的20*1个按钮和20*4个标签扩展为30*1个按钮和30*4个标签。
逐步增加功能:1、增加平均值输出功能,正常;看来不是因为引入新变量导致的。
2、增加界面按钮,正常;
3、增加延时,崩溃。
原来是延时过长引起崩溃。
主线程中使用的QTime定时器中循环造成程序线程堵塞:
void CDelayTimer::DelayTime(unsigned long nDelayTime)//ms
{
QTime time;
time.start();
while (time.elapsed() < nDelayTime)
{
//空语句,延时效果
}
}
按照Qt中文手册中7-3 系统繁忙时的响应( Staying Responsive During Intensive Processing)的说明,改为如下可暂时使用:
void CDelayTimer::DelayTime(unsigned long nDelayTime)//ms
{
QTime time;
time.start();
while (time.elapsed() < nDelayTime)
{
//空语句,延时效果
QApplication::processEvents();
}
}
其实个人感觉也可能不是这方面的原因,也可能是某个变量在定时器和主线程中同时写,造成变量写违例,引发这种问题。
但是现在还没有找到对应的位置。
1、一个延时时照顾其他事件的知识点:
QApplication::processEvents();
2、多线程程序中定义、引入一个变量,要考虑作用范围,抱着“能不定义就不定义,能少定义就少定义”的原则。
个人感觉如果对某个变量频繁修改,那么就要积极考虑是否会引起冲突,尽量降低维护成本。
3、构建能够调试的环境,步步跟踪。
我的情况就是,开发机上可以调试,但是生产机上不能调试,郁闷的要死。
在设置QWidget字体样式、变量内容被覆盖就无法调试。
1、生产机上无法调试,还不知道是什么原因。
2、根本原因仍不明朗,暂时可用,但还需要继续研究。