• 722阅读
  • 8回复

[讨论]关于Qt应用程序中途关闭后,再重启出现应用程序已停止工作,问题事件名称:APPCRASH [复制链接]

上一主题 下一主题
离线lwei24
 

只看楼主 倒序阅读 楼主  发表于: 2023-05-16
如题,Qt应用程序中有线程,当线程仍在运行的过程中,突然关闭窗口,再重启应用程序的时候,提示:该应用程序已停止工作,问题事件名称:APPCRASH。然而,在每个类的析构函数中,都那些指针对象做了安全释放的处理和利用VLD调试并没有任何内存泄露。请问各位大佬们,你们有碰到过这样的异常吗?有什么办法可以定位或分析到是哪里出问题吗?欢迎大佬们指点一二,小弟感激不尽,在线等!!!
离线20091001753

只看该作者 1楼 发表于: 2023-05-16
窗口关闭的时候,不代表进程就立马退出。
因为它或许会等待其他线程完成。
就像 win 系统关机的时候,会提示等待其他程序结束,一样的道理。

exit(0)可以确保进程立马退出,就像你在 win 系统关机时,点击 立马关机,不再等其他程序结束。
当然,你需要在退出前保存好相关的数据。
(づ ̄ 3 ̄)づ
离线lwei24

只看该作者 2楼 发表于: 2023-05-16
回 20091001753 的帖子
20091001753:窗口关闭的时候,不代表进程就立马退出。
因为它或许会等待其他线程完成。
就像 win 系统关机的时候,会提示等待其他程序结束,一样的道理。
exit(0)可以确保进程立马退出,就像你在 win 系统关机时,点击 立马关机,不再等其他程序结束。
....... (2023-05-16 12:35) 

嗯嗯,窗口关闭时,的确不代表进程立马退出,因此,在析构函数的地方,我都对类似指针对象(包括线程)都做了安全释放。例如,当我点击关闭按钮的时候,我会将当前正在运行的线程退出,直接exit(-1),然后线程退出后,进入对应的析构函数,我也做了安全释放(quit();wait()),即便是如此,在重复中断线程关闭窗口,再重启后,第二或第三次就会提示应用程序已停止工作,问题事件名称:APPCRASH。面对这样的问题,我用了VLD去分析应用程序是否有内存泄露,但分析结果是没有内存泄露。目前我找不到任何调试的办法去定位问题出现在哪里,想问问一下您是否有什么好的办法,可以去分析或定位是哪里出问题了吗?
离线20091001753

只看该作者 3楼 发表于: 2023-05-16
关闭窗口触发的其实是 closeEvent 事件,并非析构函数。

也就是说,若程序选择等待线程结束(而你的线程迟迟不结束),那么你所定义的析构函数,是没有得到执行的。

最简单的方式就是,exit(0),当然事先保存好。
(づ ̄ 3 ̄)づ
离线lwei24

只看该作者 4楼 发表于: 2023-05-16
回 20091001753 的帖子
20091001753:关闭窗口触发的其实是 closeEvent 事件,并非析构函数。
也就是说,若程序选择等待线程结束(而你的线程迟迟不结束),那么你所定义的析构函数,是没有得到执行的。
最简单的方式就是,exit(0),当然事先保存好。 (2023-05-16 16:44) 

请问exit(0)不是正常退出吗?exit(-1)非正常退出吧,您说的事先保存好,有点没太理解,因为关闭进程,以为希望终止当前程序的所有操作。所以,我在关闭按钮出发的时候,是会判断线程是否在执行,若执行则设置结束线程的标志位为真。并发出信号,直接将线程exit(-1)。虽然关闭窗口触发的是closeEvent,而不是析构函数,但这并不影响,因为最终都会经过析构函数去安全释放所有对象指针。只不过,像线程释放的时候,即使在exit(-1)结束(没完全退出)时,它会在析构函数释放的地方等待几秒,才释放。这个倒是可能会影响用户下一次点击运行应用程序。(这个问题我也很想优化,目前没有找到办法,因为如果关闭后,就立即全部释放,不停留,这样对下一次运行才不会有很大得影响。)我测试了几次,发现中途关闭窗口,再重新启动第二或第三次就提示“appcrash错误,异常代码c0000005”。看样子可能是有野指针,但VLD没有检测出来……
离线圣域天子

只看该作者 5楼 发表于: 2023-05-16
建议改用 qApp->quit();
离线lwei24

只看该作者 6楼 发表于: 2023-05-17
回 圣域天子 的帖子
圣域天子:建议改用 qApp->quit(); (2023-05-16 21:10) 

哦哦,请问改用qApp->quit();和QThread::exit(0);或QThread::exit(-1);有什么不一样的效果或意义吗?
离线20091001753

只看该作者 7楼 发表于: 2023-05-17
exit(),就是整个程序终止,他是C语言官方自带的函数,跟 Qt 没关系
qApp->quit(),是 Qt 的程序终止,它依赖于 Qt 事件循环。
QThread::exit(),只是终止该线程,而它跟进程结束没有直接关系。

你认为窗口关闭了,那么就会立即触发窗口的析构函数,所以怀疑自己检查多遍的析构函数出了问题。
但实际情况是,窗口关闭是产生一个 closeEvent 事件,并不必然会触发窗口析构,因为窗口也是可以隐藏的 hide()

而且,就算你所有窗口都关闭了、析构了,也不代表进程就会退出。
总之,你的析构函数有没有触发,是谁阻碍了触发,这就需要你排查。
(づ ̄ 3 ̄)づ
离线lwei24

只看该作者 8楼 发表于: 2023-05-18
回 20091001753 的帖子
20091001753:exit(),就是整个程序终止,他是C语言官方自带的函数,跟 Qt 没关系
qApp->quit(),是 Qt 的程序终止,它依赖于 Qt 事件循环。
QThread::exit(),只是终止该线程,而它跟进程结束没有直接关系。
你认为窗口关闭了,那么就会立即触发窗口的析构函数,所以怀疑自己检查多遍的析 .. (2023-05-17 11:46) 

好的,多谢了
快速回复
限100 字节
 
上一个 下一个