我在调用weak_ptr的析构函数时偶尔遇到崩溃。这是精确的崩溃日志
tests(35405,0x700002602000) malloc: *** error for object
0x7fcd2010a5b0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
它抱怨的指针是weak_ptr中保存的shared_ptr_emplace对象。 weak_ptr的析构函数看起来像这样
template<class _Tp>
weak_ptr<_Tp>::~weak_ptr()
{
if (__cntrl_)
__cntrl_->__release_weak();
}
它没有崩溃的__cntrl对象(在调用__release_weak时释放)。
以下是我试图完成的崩溃功能的高级描述。我异步运行USB事务,对于每个异步事务,我将weak_ptr返回给一个允许客户端取消异步事务的对象。我将其称为CancelableToken
,它也继承自enable_shared_this
。令牌的shared_ptr由底层事务持有。在崩溃时,事务已经完成,并且CancelableToken的shared_ptr已被释放,因此只存在一个weak_ptr引用(来自enable_shared_from_this的弱引用也被删除,因为CancelableToken的底层对象已被释放),由呼叫/等待功能的堆栈保持。这是方法
virtual bool ControlSend( uint32_t address, uint32_t value )
{
bool retval = false;
shared_ptr<promise<bool>> pPromise = make_shared<promise<bool>>();
BootCommand cmd( BootCommand::BootCommandWrite, address, value );
auto fut = pPromise->get_future();
auto token = SendControlBytesVendorAsync( &cmd, sizeof( cmd ),
[this, pPromise, cmd]( shared_ptr<AUsbTransfer> pTransfer ) {
if( pTransfer->IsSuccessful()) {
DEBUG_PRINT( "Competed: 0x%x = 0x%x", cmd.address, cmd.value );
pPromise->set_value( true );
} else {
DEBUG_PRINT( "ControlSend: Failed to send Control Bytes" );
pPromise->set_value( false );
}
} );
if( fut.wait_for( m_timeout ) == future_status::ready ) {
retval = fut.get();
DEBUG_PRINT("Transaction Done 0x%x = 0x%x", cmd.address, cmd.value );
} else {
LOCK_AND_CANCEL( token );
}
DEBUG_PRINT( "Returning, token: %p", &token );
return retval;
}
SendControlBytesVendorAsync()
是一个成员函数,用于触发异步事务。当发送操作完成时,将调用传入的函数回调。回调被赋予一个shared_ptr给代表传输的对象(AUsbTransfer)。此Transfer对象是拥有CancelableToken的shared_ptr的对象。当回调退出时,pTransfer将被销毁并使用CancelableToken。
函数ControlSend()
基本上是一个等待事务完成的阻塞函数。大多数情况下,该功能运行得很好,但每隔一段时间它就像我上面提到的那样崩溃。我曾尝试在没有崩溃的情况下使用调试器,当它崩溃并且无法真正看到差异时。我没有关于如何调试的想法,可以真正使用一些帮助。如果您需要我发布更多信息,请告诉我,我会。