Wxwidget wxTimer 在应用程序关闭时导致随机访问冲突
Wxwidget wxTimer causes random access violation on application close
我在使用 wxWidgets v3.0.1 的 wxFrame window 上有一个相当简单的 wxTimer 循环,它在处理关闭事件时随机导致访问冲突(例如 file/exit 或对话框框架上的 X) , 然后在 destroy();
之前调用 m_timer.stop()
我已经通过 Whosebug 进行了挖掘,并尝试了所有我能找到的方法,但都无济于事。任何人都可以指出我可能出错的地方吗:
系统:
我在 wxApp class 中创建了一个应用程序 class 并(通过指针)传递给 wxFrame、wxPanel,因为我正在使用 wxAuiManager。
定时器正在初始化:
m_timer.SetOwner( this, ID_toolbarPaneTimer );
m_timer.Start( 2000, wxTIMER_CONTINUOUS );
Connect( ID_toolbarPaneTimer
, wxEVT_TIMER
, wxTimerEventHandler( ToolbarPane::OnTimerTick ) );
::OnTimerTick函数本身也很简单:
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;
}
}
}
}
当主对话框关闭时,工具栏窗格会执行 m_timer.stop()。当 wxApp 被销毁时,应用程序 class 也被销毁。
访问冲突中断于:
void wxTimerHiddenWindowModule::OnExit()
{
if ( ms_hwnd )
{
if ( !::DestroyWindow(ms_hwnd) )
{
wxLogLastError(wxT("DestroyWindow(wxTimerHiddenWindow)"));
}
任何关于我做错的建议都将不胜感激。
更新:
- 已检查 m_projectModel 的空指针,但没有帮助
- 我删除了计时器中的所有代码,但它仍然崩溃
- 已验证 3.0.2 更改日志中未添加任何计时器修复程序
- 应用程序没有创建任何其他线程。
我发现问题不是wxWidgets本身引起的,而是第三方应用引起的。
OP 在 Mac 上的 Parallels 虚拟机中 运行 Windows,处于 Coherence View 模式。安装在 Windows 中的 Parallels Tools 组件在此配置中使用了一个挂钩 DLL (prl_hook.dll
),它被注入所有进程并检查 window 管理调用,包括 ::DestroyWindow()
。
wxWidgets 使用隐藏的 window 来接收 wxTimer 事件。 window 由 wxTimerHiddenWindowModule
管理。 Parallels 挂钩 DLL 不喜欢这样 window - 当 wx 在其上调用 ::DestroyWindow()
作为应用程序退出时正常清理过程的一部分时,挂钩 DLL 代码有时会因访问冲突而崩溃。
停止 Parallels Tools 服务解决了问题。
我在使用 wxWidgets v3.0.1 的 wxFrame window 上有一个相当简单的 wxTimer 循环,它在处理关闭事件时随机导致访问冲突(例如 file/exit 或对话框框架上的 X) , 然后在 destroy();
之前调用 m_timer.stop()我已经通过 Whosebug 进行了挖掘,并尝试了所有我能找到的方法,但都无济于事。任何人都可以指出我可能出错的地方吗:
系统: 我在 wxApp class 中创建了一个应用程序 class 并(通过指针)传递给 wxFrame、wxPanel,因为我正在使用 wxAuiManager。
定时器正在初始化:
m_timer.SetOwner( this, ID_toolbarPaneTimer );
m_timer.Start( 2000, wxTIMER_CONTINUOUS );
Connect( ID_toolbarPaneTimer
, wxEVT_TIMER
, wxTimerEventHandler( ToolbarPane::OnTimerTick ) );
::OnTimerTick函数本身也很简单:
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;
}
}
}
}
当主对话框关闭时,工具栏窗格会执行 m_timer.stop()。当 wxApp 被销毁时,应用程序 class 也被销毁。
访问冲突中断于:
void wxTimerHiddenWindowModule::OnExit()
{
if ( ms_hwnd )
{
if ( !::DestroyWindow(ms_hwnd) )
{
wxLogLastError(wxT("DestroyWindow(wxTimerHiddenWindow)"));
}
任何关于我做错的建议都将不胜感激。
更新:
- 已检查 m_projectModel 的空指针,但没有帮助
- 我删除了计时器中的所有代码,但它仍然崩溃
- 已验证 3.0.2 更改日志中未添加任何计时器修复程序
- 应用程序没有创建任何其他线程。
我发现问题不是wxWidgets本身引起的,而是第三方应用引起的。
OP 在 Mac 上的 Parallels 虚拟机中 运行 Windows,处于 Coherence View 模式。安装在 Windows 中的 Parallels Tools 组件在此配置中使用了一个挂钩 DLL (prl_hook.dll
),它被注入所有进程并检查 window 管理调用,包括 ::DestroyWindow()
。
wxWidgets 使用隐藏的 window 来接收 wxTimer 事件。 window 由 wxTimerHiddenWindowModule
管理。 Parallels 挂钩 DLL 不喜欢这样 window - 当 wx 在其上调用 ::DestroyWindow()
作为应用程序退出时正常清理过程的一部分时,挂钩 DLL 代码有时会因访问冲突而崩溃。
停止 Parallels Tools 服务解决了问题。