【问题标题】:Why does redirecting wcout/wcerr to /dev/null cause program to crash?为什么将 wcout/wcerr 重定向到 /dev/null 会导致程序崩溃?
【发布时间】:2013-01-15 21:38:01
【问题描述】:

考虑一下我的日志记录类

void LogWriter::InitLogWriter(void)
{
    wcout.flush();
    wcerr.flush();
    COUT_BACKUP = wcout.rdbuf(); // save original cout buffer
    CERR_BACKUP = wcerr.rdbuf(); //save original cerr buffer
    FileStreamOpen = false;
    switch(m_nTraceLvl)
    {
    case OffLevel:
        StopOutput();
        break;
    case ErrorLevel:
        OutputErrorsToFile(s_TraceFile);
        break;
    case DetailLevel:
        OutputAllToFile(s_TraceFile);
        break;
    default:
        StopOutput();
        break;
    }
    wcout << "Initialize Log Writer" << endl;
}
void LogWriter::OutputAllToFile(TCHAR* fileName)
{
    wstreambuf* fb = GetFileBufferStream(fileName);

    wcout.rdbuf(fb); // push wcout buffer to file
    wcerr.rdbuf(fb); // push cerr buffer to file

    FileStreamOpen = true;
}
void LogWriter::OutputErrorsToFile(TCHAR* fileName)
{
    wstreambuf* fb = GetFileBufferStream(fileName);
    wcerr.rdbuf(fb);
    FileStreamOpen = true;
    wofstream fout("/dev/null");
    wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
}
void LogWriter::StopOutput(void)
{
    wofstream fout("/dev/null");

    wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
    wcerr.rdbuf(fout.rdbuf()); // redirect cerr to fout
}
wstreambuf* LogWriter::GetFileBufferStream(TCHAR* fileName)
{
    filestr.open(fileName);
    return filestr.rdbuf();   // get file's streambuf
}
void LogWriter::Dispose()
{
    wcout << "Kill Log Writer" << endl;
    wcout.rdbuf(COUT_BACKUP); // restore the original stream buffer
    wcerr.rdbuf(CERR_BACKUP);

    if(FileStreamOpen)
    {
        filestr.close();
    }
}

现在,如果我将 Tracing 设置为 DetailLevel (2),一切都很好。我所有的日志记录都到文件中。但是如果我选择 OffLevel 或 ErrorLevel 我的程序崩溃.. 我的调试器没有打开所以我添加了 cout

wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'

作为我的罪魁祸首...我首先重定向 wcout,然后重定向 wcerr 并且它有效(但尚未调用 wcerr)

所以这是我的问题?我应该先处理 wcout 吗?我先尝试冲洗..那没有用..所以我不知道。我做错了什么?

另外作为奖励.. 为什么在我关闭 LogWriter 之前我的所有输出都不会进入文件? IE LogWriter::Dispose()

【问题讨论】:

  • 我只会在底部使用更明确的功能。 C 流甚至系统特定的代码。记录器的可靠性很重要。
  • 我认为这可能会有所帮助......但我害怕我不知道你的意思。我是一个 java/C# 人,并被投入到这个 C++ 程序中。我遇到的一个问题是输出大字节数组(大约 192 字节),它会崩溃。当我切换到这个时,我没有那个问题
  • 至于额外的问题——std::fstream 是缓冲的,所以它会在需要的时候写入,除非你通过 "
  • 我所有的日志调用都有endl(我在stdafx.h中使用命名空间std)所以它对我来说没有意义..但我会尝试std::flush的东西..我定义了 tout wcout

标签: c++ redirect wofstream


【解决方案1】:

您崩溃是因为wofstream fout("/dev/null"); 是在堆栈上创建的,并且在您退出函数后立即被销毁。

像对待文件一样对待“/dev/null”。也就是说,在StopOutput() 中调用OutputErrorsToFile("/dev/null")。实际上你甚至不需要/dev/null,只要使用wcout.rdbuf(NULL),应该也能更快。

要写入文件立即调用flush或使用std::flush manipilator。

【讨论】:

  • 你先生..让我很开心:)
猜你喜欢
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2014-10-05
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2020-05-26
相关资源
最近更新 更多