как диагностировать исключение в выпуске comptr при выходе из приложения

0

У меня есть приложение, которое предоставляет исключение, когда приложение выходит. Callstack показывает, что исключение происходит из CComPtr :: release при вызове CoUnintialize.

>   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. Фактически исключение - это то же самое "нарушение доступа", но трассировка стека различна. Я не очень разбираюсь в windbg, чтобы понять это. Все указатели в windbg to проследить?
  • Я попытался удалить какой-то код, но он также не разбудил.
  • 0
    К моменту вызова CoUninitialize все действия COM должны быть прекращены. У тебя этого не происходит.
  • 0
    Повреждения кучи вполне достаточно, чтобы объяснить это.
Теги:
exception
com
visual-studio-2010
atl

2 ответа

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 в конструкторе MainWindow и вызвал ptDialog-> exec() согласно моим потребностям в методах MainWindow, а именно:

//в 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 будет выпущен только в конце приложения, избегая проблемы.

0

Это, скорее всего, происходит из-за неправильного порядка выпуска объектов. Рассмотрим следующий пример: COM-объект A предназначен для собственного COM-объекта B, поэтому ожидаемая последовательность заключается в том, что объект A явно называется Release() и в нем destructor он вызовет Release() для объекта B. Теперь, когда CoUnintialize() называется COM, принудительно освобождает все COM-объекты в некоторой последовательности. Таким образом, существует вероятность, что объект B сначала называется Release() а теперь объект A содержит обвисший указатель на то, что он считает объектом B, и поэтому, когда вызывается объект A Release() он пытается использовать обвисший указатель и запускается неопределенное поведение.

Решение, поэтому эта проблема явно выделяет объекты в правильной последовательности до CoUnintialize().

  • 0
    проблема в том, что в этом случае CoUnintialize не вызывается из моего кода. Я поставил точку останова в своем коде при вызове CoUnintialize, и его никогда не вызывают. Я получаю исключение только до этого.
  • 0
    Как видно из стековой трассировки, какой-то поток разрушается, так что вы случайно используете рабочий поток? Если нет, это означает, что ваш основной поток завершен, и если он делает это без вашего вызова CoUninitialize, он, вероятно, уничтожается из-за какой-то серьезной ошибки (поэтому среда выполнения вызывает ExitProcess). Насколько я помню, можно установить точки останова для функций API, таких как CoUninitialize. Если вы сделаете это, вы можете лучше понять, какой код вызывает CoUninitialize.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню