Search code examples
c++wxwidgetsaccess-violationshutdown

Wxwidget wxTimer causes random access violation on application close


I have a fairly simple wxTimer loop on a wxFrame window using wxWidgets v3.0.1 that randomly causes an access violation when a close event is handled (e.g. file/exit or X on dialog frame), the m_timer.stop() is then called before destroy();

I have dredged through StackOVerflow and tried everything I could find to no avail. Can anyone give me a pointer to where I could be going wrong please:

System: I have an Application class created in the wxApp class and being passed (by pointer) to a wxFrame, wxPanel as I am using wxAuiManager.

The timer is being initialised by:

m_timer.SetOwner( this, ID_toolbarPaneTimer );
m_timer.Start( 2000, wxTIMER_CONTINUOUS );    

Connect( ID_toolbarPaneTimer
       , wxEVT_TIMER
       , wxTimerEventHandler( ToolbarPane::OnTimerTick ) );

The ::OnTimerTick function itself is also very simple:

void ToolbarPane::OnTimerTick( wxTimerEvent &event )
{
    AssetDataTransaction *transaction = NULL;
    int transactionsWaiting = m_projectModel->GetNumberOfAssetTransactions();

    if ( transactionsWaiting > 0 )
    {
        for ( int transNo = 0; transNo < transactionsWaiting; transNo++ )
        {
            transaction = m_projectModel->GetTopAssetTransaction();

            switch( transaction->GetType() )
            {
            case AssetDataTransactionType_add:
                AddAssetItem( transaction );
                m_projectModel->PopTopAssetTransaction();
                break;

            default:
                break;
            }
        }
    }
}

When the main dialog is closed the toolbar pane is does a m_timer.stop(). Application class is destroyed when wxApp is destroyed.

The access violation breaks on:

void wxTimerHiddenWindowModule::OnExit()
{
    if ( ms_hwnd )
    {
        if ( !::DestroyWindow(ms_hwnd) )
        {
            wxLogLastError(wxT("DestroyWindow(wxTimerHiddenWindow)"));
        }

Any suggestions on what I am doing wrong would really be appreciated.

Updates:

  1. Checked for Null pointer for m_projectModel and didn't help
  2. I have removed all of the code within the timer and it still crashes
  3. Verified no fixes for timers were added to 3.0.2 change log
  4. The application does not create any other threads.

Solution

  • I turned out that the issue was caused not by wxWidgets itself, but by a third-party application.

    The OP was running Windows in a Parallels virtual machine on a Mac, in Coherence View mode. The Parallels Tools component that is installed in Windows in this configuration uses a hook DLL (prl_hook.dll) that is injected in all processes and inspects window management calls, including ::DestroyWindow().

    wxWidgets uses a hidden window to receive wxTimer events. The window is managed by wxTimerHiddenWindowModule. The Parallels hook DLL doesn't like that window - when wx calls ::DestroyWindow() on it as part of the normal cleanup procedure upon app exit, the hook DLL code sometimes crashes with an access violation.

    Stopping the Parallels Tools services solved the problem.