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:
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.