我需要一些额外的眼睛来看问题。我们的应用程序在内部使用log4cplus。目前,我们的产品在CentOS 6.x上受支持。我正在努力将我们的产品转移到CentOS 7.我收到此错误*** Error in '/usr/bin/python': free(): invalid next size (fast): 0x000000000071c740 ***
。
检查堆栈跟踪显示问题来自log4cplus代码。我们的代码调用log4cplus::initialize()
,然后打开一个appender,如下所示:
void InitializeAppender(std::string fileName)
{
// Default appender will be rolling files that roll at 10MB.
// Immediate flush is set to true for now. This is great for testing, but may not be so good for general use...
log4cplus::SharedAppenderPtr appender(new log4cplus::RollingFileAppender(fileName, 1024 * 1024 * 10, 2, true, false));
std::auto_ptr<log4cplus::Layout> pLayout(new log4cplus::PatternLayout("%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%i] [%t] %-x %m%n"));
appender->setLayout(pLayout);
log4cplus::Logger root = log4cplus::Logger::getRoot();
root.removeAllAppenders();
root.addAppender(appender);
}
在这个函数的第一行,下降到log4cplus代码最终会导致堆损坏(至少我可以告诉)和分段错误。
log4cplus的代码对于这篇文章来说太多了,所以我只会发布相关部分(如果你对完整的#34; sha-bang&#34感到好奇;你可以从sourceforge下载,我是要提供链接但是sourceforge目前处于离线状态,如果你确实获得了源码,我使用1.2.0-rc3)。堆栈跟踪的摘录:
#0 0x00007f94e977a5c9 in raise () from /lib64/libc.so.6
#1 0x00007f94e977bcd8 in abort () from /lib64/libc.so.6
#2 0x00007f94e97badb7 in __libc_message () from /lib64/libc.so.6
#3 0x00007f94e97c219d in _int_free () from /lib64/libc.so.6
#4 0x00007f94e2357bca in _M_dispose (__a=..., this=0x22759e0) at /usr/include/c++/4.8.2/bits/basic_string.h:249
#5 ~basic_string (this=0x7fff5bdbbc00, __in_chrg=<optimized out>)
at /usr/include/c++/4.8.2/bits/basic_string.h:539
#6 log4cplus::helpers::LogLog::set_tristate_from_env (result=result@entry=0x2259e90,
envvar_name=envvar_name@entry=0x7f94e2482c0b "LOG4CPLUS_LOGLOG_DEBUGENABLED") at src/loglog.cxx:155
#7 0x00007f94e2357d2f in log4cplus::helpers::LogLog::get_debug_mode (this=0x2259e88) at src/loglog.cxx:145
您会注意到log4cplus::helpers::LogLog::get_debug_mode
来电log4cplus::helpers::LogLog::set_tristate_from_env
。在set_tristate_from_env
的出口处,调用std::basic_string<>
的析构函数。事前的东西腐蚀了堆,我不知道在哪里。这两个功能相当无害,但无论如何我都会发布它们。
// from loglog.cxx in log4cplus sources
// tchar is typedef char tchar in this build (it is not UNICODE)
// at least, I believe that to be the case. I will test.
// TriState is an enum with 3 values
void
LogLog::set_tristate_from_env (TriState * result, tchar const * envvar_name)
{
tstring envvar_value;
// the prototype for get_env_var()
// get_env_var(tstring& value, tstring const& name)
bool exists = internal::get_env_var (envvar_value, envvar_name);
bool value = false;
if (exists && internal::parse_bool (value, envvar_value) && value)
*result = TriTrue;
else
*result = TriFalse;
}
get_debug_mode的代码
// also from loglog.cxx in log4cplus sources
// LOG4CPLUS_TEXT macro is an indirection for adding the preceding
// 'L' to the string necessary when UNICODE aware. Otherwise, it's
// simply the string
bool
LogLog::get_debug_mode () const
{
if (LOG4CPLUS_UNLIKELY (debugEnabled == TriUndef))
set_tristate_from_env (&debugEnabled,
LOG4CPLUS_TEXT ("LOG4CPLUS_LOGLOG_DEBUGENABLED"));
return debugEnabled && ! get_quiet_mode ();
}
万一它是相关的,这里是get_env_var
来自set_tristate_from_env
// from env.cxx in log4cplus sources
bool
get_env_var (tstring & value, tstring const & name)
{
#if defined (_WIN32) && defined (UNICODE)
tchar const * val = _wgetenv (name.c_str ());
if (val)
value = val;
return !! val;
#else
char const * val
= std::getenv (LOG4CPLUS_TSTRING_TO_STRING (name).c_str ());
if (val)
value = LOG4CPLUS_STRING_TO_TSTRING (val);
return !! val;
#endif
}