wishel 发表于 2010-1-8 16:36:16

疑难杂症:ACE_Guard<ACE_Recursive_Thread_Mutex>

崩溃在 这句:
ACE_Guard<ACE_Recursive_Thread_Mutex> lock( mutex ); // ipcservice.h @ 155


Stacks:
1: WARNING: Stack unwind information not available. Following frames may be wrong.
2: ntdll+0x2fc47
3: ntdll+0x2fb56
4: *******!ACE_OS::thread_mutex_lock+0xd
5: *******!ACE_OS::recursive_mutex_lock+0xc
6: *******!ACE_Recursive_Thread_Mutex::acquire+0x10
7: *******!ACE_Guard<ACE_Recursive_Thread_Mutex>::acquire+0x11
8: *******!ACE_Guard<ACE_Recursive_Thread_Mutex>::ACE_Guard<ACE_Recursive_Thread_Mutex>+0x21
9: *******!XPP::IPC::Service::IService<ACE_MEM_Stream,ACE_Recursive_Thread_Mutex>::write_ipc+0x37
..................


大家遇到过这种状况么?

shenming 发表于 2010-1-10 10:46:33

我一般这样用

这个问题遇到过。

你的那个堆栈错误故障,一般发生在一个局部区域又有释放又有生成造成互相缠绕,这时会发生堆栈错误,查错的方式一般是先把出错的变量定义为全局的,没有了错误在细细排查。


我一般这样用,几年了,没问题,第一个参数是类型,第二个是一个守卫变量,第三个是锁变量,第四个是失败的返回值
ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex,local_guard,this->lock,result);

[ 本帖最后由 shenming 于 2010-1-10 10:47 编辑 ]

wishel 发表于 2010-1-11 16:20:19

写了个小测试程序,确实ACE_Recursive_Thread_Mutex的release和accquire不配对时,多线程会崩溃的。

wishel 发表于 2010-1-12 16:26:28

再次看了下源码,貌似不配对也没问题
template <class ACE_LOCK> ACE_INLINE int
ACE_Guard<ACE_LOCK>::release (void)
{
if (this->owner_ == -1)
    return -1;
else
    {
      this->owner_ = -1;
      return this->lock_->release ();
    }
}

template <class ACE_LOCK> ACE_INLINE
ACE_Guard<ACE_LOCK>::~ACE_Guard (void)
{
this->release ();
}
保证多次release也没问题

wishel 发表于 2010-1-12 16:31:37

但是这段代码


#include "ace/Timer_Queue.h"
#include "ace/Reactor.h"
#include "ace/High_Res_Timer.h"
#include "ace/Trace.h"
#include "ace/Recursive_Thread_Mutex.h"
#include "ace/Log_Msg.h"
#include "ace/Thread_Manager.h"
#include "ace/OS.h"

void* f (void* mutex) {
ACE_Guard<ACE_Recursive_Thread_Mutex> lock( *(ACE_Recursive_Thread_Mutex*)mutex );
ACE_DEBUG ((LM_DEBUG, "haha f\n"));
ACE_OS::sleep(2);
return 0;
}


int ACE_TMAIN(int argc, ACE_TCHAR **argv)
{
ACE_Recursive_Thread_Mutex mutex;
ACE_Guard<ACE_Recursive_Thread_Mutex> lock( mutex );

lock.release();
lock.release();
ACE_DEBUG ((LM_DEBUG, "haha 1\n"));
ACE_Thread_Manager::instance()->spawn((ACE_THR_FUNC)f, (void*) &mutex, THR_DETACHED | THR_SCOPE_PROCESS);
ACE_OS::sleep(1);
ACE_DEBUG ((LM_DEBUG, "haha 2\n"));
lock.release();
ACE_Guard<ACE_Recursive_Thread_Mutex> lock1( mutex );
ACE_DEBUG ((LM_DEBUG, "haha 3\n"));
lock.release();

ACE_DEBUG ((LM_DEBUG, "haha here?\n"));
ACE_Thread_Manager::instance()->wait();
ACE_DEBUG ((LM_DEBUG, "haha there?\n"));
   
return 0;
}


崩溃的几率很高。但我把ACE_DEBUG语句注释掉或者改成cout<< 就没崩溃过。
有时候崩溃又很难重现,郁闷。。。
一直对ACE_DEBUG的线程安全性存疑。。。

freeeyes 发表于 2010-1-13 14:56:28

这个错误我也遇到过,在win下,我也在寻找里面机理。
等我拿楼主的代码做做实验。

wishel 发表于 2010-1-15 13:12:52

4楼的程序,在vista下崩溃重现比较容易。但在xp和linux下还没遇到过。目前尚未找到具体原因

1楼的问题应该是另一个问题,好像找到原因了,传入的mutex是一个ACE_Recursive_Thread_Mutex*
有可能是NULL或野指针
页: [1]
查看完整版本: 疑难杂症:ACE_Guard<ACE_Recursive_Thread_Mutex>