2013-11-21 21 views
0

我有应用程序退出时发生异常的应用程序。 Callstack显示当CoUnintialize被调用时异常来自CComPtr :: release。如何在应用程序退出时诊断comptr版本中的异常

> 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中什么是真正的例外是相同的“访问冲突”,但堆栈跟踪different.I不是很windbg的专家来弄清楚这一点。windbg中的任何指针都可以追踪它?
  • 我试图删除一些代码,但它也没有炒锅。
+0

到'CoUninitialize'调用的时刻,您应该终止所有COM活动。你没有发生。 –

+0

堆腐败足以解释这一点。 –

回答

0

这很可能是因为错误的对象发布顺序而发生的。考虑下面的例子:COM对象A意味着拥有COM对象B,因此预期的序列是该对象A明确地在其上析出并调用Release(),它将在对象B上调用Release()。现在,当调用CoUnintialize()时,在一些序列中释放所有COM对象。因此,有可能首先调用对象B的Release(),现在对象A拥有一个悬挂指针,指向它认为是对象B的对象,因此当对象A Release()被调用时,它会尝试使用悬挂指针并运行到未定义的行为。

这个问题的解决方案是在调用CoUnintialize()之前明确释放正确序列中的对象。

+0

问题是,在这种情况下,CoUnintialize不会从我的代码中调用。我在调用CoUnintialize的代码中放入了断点,并且它永远不会被调用。我只在这之前得到例外。 – anand

+0

正如我们从堆栈跟踪中看到的那样,某个线程正在被破坏,那么您是否有机会使用一个工作线程?如果不是,那意味着你的主线程结束了,如果没有你调用CoUninitialize,它可能会因为一些严重的错误而被销毁(所以运行时调用ExitProcess)。据我记得,可以在CoUninitialize等API函数上设置断点。如果你这样做,你可能会得到更好的线索,代码调用CoUninitialize。 – StuartRedmann

0

我有这个问题后红色

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; 
..... 
} 

所以我给了一个新的QfileDialog到ptDialog在主窗口的构造,并呼吁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中,将只在应用端,避开这个问题。

相关问题