I have a ostream-based subclass which captures debug messages of my program.

/** @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

How I use this class:

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

Issue: The class work fine when the application exits normally. But in case of crashing (e.g. array index out of bound, etc), the 'tout' did print out all message to console, but the 'debugFile' does not capture all the printout.

Question: So, how to properly flush the ostream buffer to output file in case when the application crash?

有帮助吗?

解决方案

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.

其他提示

I am glad to answer you question. Once I met this problem. I suggest you can use dbghelp.dll. You can search something about dbghelp.dll. It is very useful.

Here some examples: First, you can write a function to handle the exception.

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

Second, create a exception filter. You can also create a dump file here.

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

Then, call the function SetUnhandledExceptionFilter to set the exception filter. You must call this function before exception happens.

SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);

Sometimes, you can use __try and __catch.

For example:

__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.
}

It's all. Nice day, man.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top