为什么重定向wcout/wcerr到/dev/null会导致程序崩溃?

Why does redirecting wcout/wcerr to /dev/null cause program to crash?

本文关键字:程序 崩溃 dev wcout 重定向 wcerr 为什么 null      更新时间:2023-10-16

考虑我的日志类

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();
    }
}

现在,如果我设置我的跟踪到DetailLevel(2),一切都很好。我所有的日志记录都保存在文件中。但是如果我选择OffLevel或ErrorLevel我的程序崩溃了。我的调试器没有打开所以我添加了cout <<"."在每一行(我讨厌这样做,但它工作),它指向我

wcout.rdbuf(fout.rdbuf()); // redirect 'cout' to a 'fout'
作为我的罪魁祸首…我切换重定向wcout与wcerr被重定向,它工作(但wcerr还没有被调用)

这就是我的问题?我应该先处理掉wcout吗?我试过先冲水,但没有用。所以我不知道。我做错了什么?

也作为奖励…为什么我所有的输出不去文件,直到我关闭我的LogWriter?IE LogWriter: Dispose ()

会导致崩溃,因为wofstream fout("/dev/null");是在堆栈上创建的,一旦退出函数就会被销毁。

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

立即写入文件调用flush或使用std::flush操纵符