如何在应用程序退出时诊断comptr版本中的异常

how to diagnose exception in comptr release on application exit

本文关键字:版本 comptr 异常 诊断 应用程序 退出      更新时间:2023-10-16

我有一个应用程序在应用程序退出时发出异常。调用堆栈显示,当调用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将只在应用程序端发布,从而避免了这个问题。