4

我有一个基于 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 缓冲区刷新到输出文件?

4

2 回答 2

3

One way is to use a crash handler. In windows, this is in the form of dbghlp.dll and the just-in-time debugging subsystem.

But by far the easiest way is to flush on every message in one of two ways:

  1. Keep the file open, and call flush after every message.
  2. Open the file in append mode, write, and close the file every time you write a message.

I believe that using endl instead of "\n" will implicitly flush.

于 2013-05-16T05:21:43.467 回答
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.
}

就是这样。美好的一天,伙计。

于 2013-05-16T05:55:47.690 回答