在log4cplus中堆坏了

时间:2015-02-10 18:11:25

标签: c++ allocation heap-corruption

我需要一些额外的眼睛来看问题。我们的应用程序在内部使用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
}

0 个答案:

没有答案