2013-05-16 36 views
3

我有一个基于ostream的子类,它捕获我的程序的调试消息。如何在应用程序崩溃时刷新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缓冲区刷新为输出文件?

回答

3

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

但是迄今为止最简单的方法是在以下两种方式之一对每封邮件刷新:

  1. 保持文件打开,每一个消息后打电话flush
  2. 以追加模式打开文件,每次写入消息时写入并关闭文件。

我相信使用endl而不是"\n"会隐式刷新。

+1

你是对的。 'endl'输出一个换行符并刷新流。 – chris

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

这一切。美好的一天,男人。

相关问题