Как очистить 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» не захватил все распечатки.

Вопрос: Итак, как правильно очистить буфер вывода в выходной файл в случае сбоя приложения?

4

Решение

Одним из способов является использование обработчика сбоев. В окнах это в виде dbghlp.dll и подсистема отладки точно в срок.

Но, безусловно, самый простой способ — очистить каждое сообщение одним из двух способов:

  1. Держите файл открытым и звоните flush после каждого сообщения.
  2. Откройте файл в режиме добавления, пишите и закрывайте файл каждый раз, когда пишете сообщение.

Я считаю, что с помощью endl вместо "\n" будет неявно сбрасывать.

3

Другие решения

Я рад ответить на ваш вопрос. Однажды я встретил эту проблему. Я предлагаю вам использовать 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.
}

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

1

По вопросам рекламы [email protected]