如何在应用程序退出时诊断comptr版本中的异常
how to diagnose exception in comptr release on application exit
我有一个应用程序在应用程序退出时发出异常。调用堆栈显示,当调用CoUnintialize时,异常来自CComPtr::release。
> ieframe.dll!ATL::CComPtr<IWebBrowser2>::Release() + 0x5b bytes
ieframe.dll!CConnectionPoint::UnadviseAll() + 0x131d0 bytes
ieframe.dll!CConnectionPoint::~CConnectionPoint() + 0x18 bytes
ieframe.dll!CShellOcx::~CShellOcx() + 0xf7 bytes
ieframe.dll!CWebBrowserOC::`scalar deleting destructor'() + 0x14 bytes
ieframe.dll!CAggregatedUnknown::CUnkInner::Release() + 0x474a1 bytes
ole32.dll!CStdIdentity::ReleaseCtrlUnk() Line 1149 C++
ole32.dll!CStdMarshal::Disconnect(unsigned long dwType) Line 3454 C++
ole32.dll!CStdMarshal::DisconnectAndRelease(unsigned long dwType) Line 3161 + 0x11 bytes C++
ole32.dll!COIDTable::ThreadCleanup() + 0x31bed bytes C++
ole32.dll!FinishShutdown() Line 1035 C++
ole32.dll!ApartmentUninitialize(int fHostThread) Line 1291 C++
ole32.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 2709 + 0x7 bytes C++
ole32.dll!CoUninitialize() Line 2632 C++
imm32.dll!000007feff3832f2()
[Frames below may be incorrect and/or missing, no symbols loaded for imm32.dll]
msctf.dll!000007fefeea7d59()
ntdll.dll!RtlProcessFlsData() + 0x84 bytes
ntdll.dll!LdrShutdownThread() + 0x4b bytes
ntdll.dll!RtlExitUserThread() + 0x38 bytes
IEShims.dll!NS_CreateThread::DesktopIE_ThreadProc() + 0xd6 bytes
kernel32.dll!BaseThreadInitThunk() + 0xd bytes
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
例外情况是访问违规
你们遇到过这样的情况吗?我能用什么策略来找出这件事的根本原因?到目前为止,我已经完成了
- 我使用了windbg,但我在windbg中得到的异常与我在VS2010中得到的不同。实际上,异常是相同的"访问违规",但堆栈跟踪不同。我不是一个很擅长应付这种情况的人。有什么线索可以追踪它吗
- 我试图删除一些代码,但也没有成功
这很可能是因为对象发布顺序错误。考虑以下示例:COM对象A意味着拥有COM对象B,因此预期的序列是对象A在上显式调用Release()
,在它的析构函数中它将在对象B上调用Release()
。现在,当调用CoUnintialize()
时,COM将强制释放某个序列中的所有COM对象。因此,对象B有可能首先被称为Release()
,现在对象a持有一个悬空指针,指向它认为是对象B的对象,因此当对象a被调用Release()
时,它试图利用悬空指针,并陷入未定义的行为。
这个问题的解决方案是在调用CoUnintialize()
之前以正确的顺序显式释放对象。
我有这个问题,在红色之后
http://mfctips.com/2012/10/29/cfiledialogdomodal-causes-access-violation/
我怀疑问题是将QFileDialog作为Qmainwindow方法的局部变量。然后我把我的Qfiledialog作为QMainwindow的私人成员解决了这个问题,如下所示:
//在MainWindow.h 中
class MainWindow : public QMainWindow
{
Q_OBJECT
......
private:
......
QFileDialog *ptDialog;
.....
}
因此,我在MainWindow构造函数中为ptDialog提供了一个新的QfileDialog,并根据我在MainWindow方法中的需要调用ptDialog->exec(),如下所示:
//在MainWindow.cpp 中
//构造函数
MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
.....
ptDialog=new QFileDialog(this, tr("Abrir Imagem"),QCoreApplication::applicationDirPath(), "Imagens (*.png *.jpg *.jpeg *.bmp)");
......
}
//我想使用QFileDialog 的任何方法
void MainWindow::LoadFile()
{
if(ptDialog->exec())
{
SetFile(ptDialog->selectedFiles().first());
}
}
我认为,通过这种方式,Qmainwindow将只在应用程序端发布,从而避免了这个问题。
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 导入库可以跨dll版本工作吗
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 不同的Visual Studio版本中缺少.dll
- 用符号版本替换对函数的所有调用
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 我需要分发哪些版本的可再分发文件
- CV_OCL_RUN宏如何在OpenCV(版本3.4.5)的goodFeaturesToTrack实现中工作?
- 在运行时读取 libstdc++ 版本
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- Vulkan SDK 版本 1.1.85.0 在 Kubuntu 18.10 上链接
- 如何正确实现与基类不同的版本?
- 从预处理器获取 Windows 版本(C++ Win32)
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 如何在C++中将 Python 字符串转换为其转义版本?
- 如何在应用程序退出时诊断comptr版本中的异常