返回后访问违规?我该如何调试这个?

问题描述 投票:0回答:1

我们的代码记录各种有意义的事件。通常日志记录工作得很好,但今天日志功能在返回时导致访问冲突。我猜测堆以某种方式损坏了,但我不太清楚为什么。日志功能几乎在所有情况下都能工作,但现在我记录的文件名稍长一些。我哪里没看到问题?

std::string Format(const char* fmt, ...)
{
    char buf[1 << 16]; // 65536
    va_list args;
    va_start(args, fmt);
    vsprintf(buf, fmt, args);
    va_end(args);
    return std::string(buf);
} // <-- Access Violation (0xC0000005) upon returning


#define LOG_DEBUG(fmt, ...)                                      \
{                                                                \
    ILogger* logger = LoggerFactory::GetLogger();                \
    if (logger)                                                  \
    {                                                            \
        std::string log = Format(fmt, ##__VA_ARGS__);            \
        logger->WriteLog(LOG_LEVEL_DEBUG, log.c_str());          \
    }                                                            \
}


static int doSomething(char* szMsg, const int nLength, ...)
{
    // Normally, this executes just fine.
    LOG_DEBUG("Message = %s, length = %d", szMsg, nLength);

    // ... do some things
}

程序退出并显示消息:

0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
。该地址对我来说似乎很可疑,为什么它会被最大化?

对于它的价值来说,

szMsg
被分配给一个非常长的字符串,其形式为:

application_specific_data\rϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷ
ϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷ
ϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷ
ϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷ
ϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷ

并且

nLength
65536

无论如何,我不太确定如何思考此类问题,即使对于这个确切的场景没有明确的答案,我该如何调试呢?我应该注意什么?我可以忽略什么?

c++ debugging segmentation-fault access-violation
1个回答
1
投票

返回时的访问冲突几乎总是破坏不是堆的结果,而是堆栈

具体来说,在这种情况下,堆栈上的返回地址已被0xffffffff覆盖。当本地缓冲区溢出时,这种情况经常发生。

显然,溢出的缓冲区是

char buf[1 << 16];

如果您有一个比缓冲区大小长的字符串,则可能会发生这种情况,而如果您不小心有一个忘记以空终止的字符串,则很容易发生这种情况。

为了保护自己免受此问题影响永远不要使用

vsprintf()
(在我看来该功能甚至不应该存在)始终使用
vsnprintf()
。这不会修复创建非常长的字符串的错误,但它可以避免您的程序因该错误而崩溃和烧毁。

© www.soinside.com 2019 - 2024. All rights reserved.