找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 5932|回复: 5

ACE日志策略出现的crash问题

[复制链接]
发表于 2010-3-29 14:15:43 | 显示全部楼层 |阅读模式
ACE的日志策略中没有按天分割的方法(有按文件大小的方法),我自己用reactor+实时器实现了一个:
在每天的零点, 定时器到期:
以下是handle_timeout方法:

int CXXXXTimer::handle_timeout(const ACE_Time_Value &current_time,
           const void *act /* = 0 */)
{
int nRet = 0;
init_log_config();
return nRet;
}

int init_log_config()
{
if (ACE_LOG_MSG->acquire())
  return -1;
ACE_LOG_MSG->clr_flags (ACE_Log_Msg::OSTREAM);
// 先保存先前的输出
ACE_OSTREAM_TYPE *old_output = ACE_LOG_MSG->msg_ostream();
// 日志文件名
std::string strLogFilePath;
CUtility::GetAppPath(strLogFilePath);
std::string strDay = CUtility::get_current_day(); // CUtility::get_current_day()返回类似于这样的字符串:2010-03-29
strLogFilePath += strDay;
  strLogFilePath += ".log";

ACE_OSTREAM_TYPE *output = new std::ofstream (strLogFilePath.c_str(),std::ios_base::out | std::ios_base::app);
ACE_LOG_MSG->msg_ostream (output, 1);
ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM);

if (old_output)
{
#if defined (ACE_LACKS_IOSTREAM_TOTALLY)
  FILE *output_file = (FILE *)old_output;
  ACE_OS::fclose (output_file);
#else
  ofstream *output_file = (ofstream *)old_output;
  output_file->close ();
#endif /* ACE_LACKS_IOSTREAM_TOTALLY */
  delete old_output;
  old_output = 0;
}
ACE_LOG_MSG->release();
return 0;
}

现在的问题是: 第当定时器当期: handle_timeout方法执行后, 能生成一个正确的文件名,如今天的日志文件名为2010-02-29.log,到了2010-03-30的零点就会生成名称为2010-03-30.log的日志文件. 此后的一调用ACE_DEBUG就会crash掉.
堆栈如下:
(1)  ACEd.dll!std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...})  行81 + 0x28 字节 C++
(2)  ACEd.dll!std::basic_ostream<char,std::char_traits<char> >::sentry::sentry(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...})  行99 + 0x3a 字节 C++
(3)  ACEd.dll!std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...}, const char * _Val=0x09f7ac38)  行751 + 0xc 字节 C++
(4)  ACEd.dll!ACE_Log_Record::print(const char * host_name=0x00000000, unsigned long verbose_flag=5, std::basic_ostream<char,std::char_traits<char> > & s={...})  行399 + 0xd 字节 C++
(5)  ACEd.dll!ACE_Log_Msg::log(ACE_Log_Record & log_record={...}, int suppress_stderr=0)  行2220 C++
(6)  ACEd.dll!ACE_Log_Msg::log(const char * format_str=0x004fe487, ACE_Log_Priority log_priority=LM_DEBUG, char * argp=0x0667d934)  行2069 + 0x11 字节 C++
(7)  ACEd.dll!ACE_Log_Msg::log(ACE_Log_Priority log_priority=LM_DEBUG, const char * format_str=0x004fe440, ...)  行953 + 0x14 字节 C++
(8)  XXX.exe!XXX_Progress(const char * package=0x0667dc88, std::basic_string<char,std::char_traits<char>,std::allocator<char> > & result="", HLL_COMM_TYPE::InterfaceType ift=IFT_CLIENT)  行37 + 0xea 字节 C++
.................

上面的(1)对应的源代码为:ostream中的(标记为红色)
  __CLR_OR_THIS_CALL _Sentry_base(_Myt& _Ostr)
   : _Myostr(_Ostr)
   { // lock the stream buffer, if there
   if (_Myostr.rdbuf() != 0)
    _Myostr.rdbuf()->_Lock();   // 这里是ostream中的81行
   }

上面的(2)对应的源代码为:ostream中的(标记为红色)
  explicit __CLR_OR_THIS_CALL sentry(_Myt& _Ostr)
   : _Sentry_base(_Ostr)       // 这里是ostream中的98行
   { // construct locking and testing stream
   if (_Ostr.good() && _Ostr.tie() != 0)
    _Ostr.tie()->flush();
   _Ok = _Ostr.good(); // store test only after flushing tie
   }

我想可能前后两个输出流死锁(具体什么原因我也搞不清). 不知道有没有遇过个这个问题. 另外ACE_DEBUG在多个线程中调用.

此外我也注意到另一个帖子:
http://www.acejoy.com/bbs/viewthread.php?tid=944&extra=page%3D1
以及:
http://www.cppblog.com/elva/archive/2008/07/31/57534.html

如果实现无法解决,只好换用其它方法来实现输出到日志了.

谢谢大家!!!
 楼主| 发表于 2010-3-29 14:41:16 | 显示全部楼层

dump信息.

dump文件如下:

This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(1840.2aa0): Access violation - code c0000005 (first/second chance not available)
eax=00000000 ebx=00000000 ecx=aff0cf00 edx=09c47341 esi=00a4b920 edi=0000008c
eip=10035828 esp=1080caac ebp=1080cadc iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
ACE!std::operator<<<std::char_traits<char> >+0x48:
10035828 8b4804          mov     ecx,dword ptr [eax+4] ds:0023:00000004=????????
发表于 2010-3-29 16:16:39 | 显示全部楼层
这个问题我到现在也没有搞定。
上次和freeeyes一起调了一下,他那边是winxp很难重现,我这边是vista重现崩溃比较容易。
最后没找到具体原因。
 楼主| 发表于 2010-3-29 16:24:00 | 显示全部楼层
是啊,  非常难搞.
我这种方式每次都会重现.
发表于 2010-3-29 21:40:03 | 显示全部楼层
每次都重现的,应该好调试的。
你贴的那个文章,我很早看过。
我觉得应该是线程同步导致的,你尝试修改一下,加一下线程同步操作。
发表于 2010-4-2 05:13:41 | 显示全部楼层
可能是内部的stream对象不对。
重载handle_timeout,
或在你的handle_timeout里调用它的handle_timeout.
可以发现问题。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-22 13:23 , Processed in 0.025839 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表