应用程序崩溃时如何刷新ostream

时间:2013-05-16 05:17:33

标签: c++ ostream tee

我有一个基于ostream的子类,它捕获程序的调试消息。

/** @brief Customized output stream with "tee" feature */
template <typename CharT, typename Traits = std::char_traits<CharT> >
class basic_tostream : public std::basic_ostream<CharT, Traits> {
public:
    basic_tostream(std::basic_ostream<CharT, Traits> & o1, /**< main ostream */
                   std::basic_ostream<CharT, Traits> & o2  /**< teed ostream */)
    : std::basic_ostream<CharT, Traits>(&tbuf), tbuf(o1.rdbuf(), o2.rdbuf())
    { /* empty */ }

private:
    tee_outbuf<CharT, Traits> tbuf;
}; // end_class: basic_tostream

我如何使用此课程:

std::ofstream debugFile("debug.txt")
tostream tout(std::cout, debugFile);
/* computation */
tout << "message\n";
/* other computation */

问题:当应用程序正常退出时,该类正常工作。但是在崩溃的情况下(例如,数组索引超出限制等),'tout'确实将所有消息打印到控制台,但'debugFile'不会捕获所有打印输出。

问题:那么,如果应用程序崩溃,如何正确刷新ostream缓冲区以输出文件?

2 个答案:

答案 0 :(得分:3)

一种方法是使用崩溃处理程序。在Windows中,这是dbghlp.dll和即时调试子系统的形式。

但到目前为止,最简单的方法是以两种方式之一刷新每条消息:

  1. 保持文件打开,并在每封邮件后致电flush
  2. 每次编写邮件时,以附加模式打开文件,编写并关闭文件。
  3. 我相信使用endl代替"\n"会隐式刷新。

答案 1 :(得分:1)

我很高兴回答你的问题。有一次我遇到了这个问题。我建议你可以使用dbghelp.dll。 您可以搜索有关dbghelp.dll的内容。这非常有用。

这里有一些例子: 首先,您可以编写一个函数来处理异常。

std::ostream& operator << ( std::ostream& os, const EXCEPTION_RECORD& red )
    {  
        // Write your error handlding code here!!!
    }

其次,创建一个例外过滤器。 您也可以在此处创建转储文件。

 LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
    {
     std::cerr << " Unknown Error: " << (*pExceptionInfo->ExceptionRecord ) << std::endl;
     exit( pExceptionInfo->ExceptionRecord->ExceptionCode  );
     return EXCEPTION_EXECUTE_HANDLER;
    }

然后,调用函数SetUnhandledExceptionFilter来设置异常过滤器。您必须在异常发生之前调用此函数。

SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);

有时,您可以使用__try和__catch。

例如:

__try
{
   // Which code may cause the exception, put them here!!!
} __except( EXCEPTION_EXECUTE_HANDLER )
{
   // Handle exception or write you log file here. I think it's a good idea.
}

一切都好。美好的一天,伙计。