2013-05-16 5 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

Один из способов - использовать обработчик аварии. В окнах это выглядит как 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. 
} 

Это все. Хороший день, мужик.