Windows — C ++: я должен перехватить все исключения или дать сбой программе?

У меня есть служба Windows, написанная на (Visual) C ++, с очень подробной функцией регистрации, которая часто помогает мне найти причину ошибок, с которыми иногда сталкиваются клиенты. В основном я проверяю каждое возвращаемое значение и записываю, что происходит и откуда происходят ошибки.

В идеале я хотел бы иметь такой же уровень детальной видимости исключений (таких как массив вне диапазона, деление на ноль и т. Д.). Другими словами: я хочу точно знать, откуда исходит исключение. Из соображений удобочитаемости и практичности я не хочу заключать каждые несколько строк кода в отдельные блоки try / catch.

Сегодня у меня есть одна общая ловушка, которая ловит все и регистрирует ошибку перед закрытием программы. Это хорошо с точки зрения пользователя — чистое отключение вместо сбоя приложения — но плохо для меня, потому что я получаю только общее сообщение из исключения (например, «массив вне диапазона»), но не знаю, откуда оно исходит.

Не лучше ли убрать ловушку и позволить программе аварийно завершить работу? Я мог бы направить клиента, чтобы Windows создала дамп сбоя приложения (как описано Вот). С файлом дампа WinDbg точно указывал бы мне на позицию в коде, где было сгенерировано исключение.

6

Решение

Вы можете зарегистрировать свой собственный обработчик исключений, позвонив AddVectoredExceptionHandler .

Он будет вызываться всякий раз, когда генерируется исключение, и в нем вы можете генерировать трассировку стека, которую затем можете сохранить для целей регистрации.

Написание кода для этого не совсем тривиально, но и не является ракетной операцией.

Лично я никогда не делал этого на C ++, но я был бы удивлен, если бы не было готовых библиотек, которые делают это где-либо, если у вас нет времени или желания делать это самостоятельно.

3

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

Вы можете выдавать исключения с описанием, где произошла ошибка и почему:

throw std::string("could not open this file");

Если вы не хотите писать разные описания для каждой возможной ошибки, вы можете использовать стандартные макросы __FILE__ и __LINE__:

#define _MyError std::string("error in " __FILE__ + std::to_string(__LINE__))
// ...
throw _MyError;

Если имя исходного файла и строка ошибки недостаточны и вам нужна дополнительная информация, например, трассировка стека или значения памяти, ваша программа может сгенерировать отчет об отладке. Google Breakpad — это библиотека C ++, которая позволяет делать это портативным способом. Класс wxDebugReport из библиотеки wxWidgets является альтернативой. В Windows отчеты об отладке могут включать файл мини-дампов, который может быть загружен в Visual Studio и позволяет анализировать ошибку аналогично отладке.

0

Не лучше ли убрать ловушку и позволить программе
сбой вместо?

Вы можете поймать все и

  • Напишите (более личное) сообщение о фатальной ошибке, которая вынудила приложение закрыться. Не позволяйте программе продолжаться: вы не знаете, что и где произошло. Продолжение может привести к повреждению данных пользователя, последующих ошибок и т. Д.
  • Скажите пользователю, чтобы он связался с вами, чтобы уточнить, что он сделал и что случилось.
  • Скажите пользователю включить файл журнала, созданный вашим приложением.

Если вы не сделаете что-то подобное, то с таким же успехом можете убрать ловушку.

Из соображений удобочитаемости и практичности не хочу оборачивать
каждые несколько строк кода в отдельные блоки try / catch.

И все же, если вы хотите, чтобы ваша программа могла восстанавливаться, это именно то, что вам нужно сделать. Что вы могли бы сделать, это

  • Сообщите пользователю, что произошло, возможно, что-то не так с вводом, который мог его вызвать. Не делайте это звучать технически.
  • Сохраните любые данные, введенные пользователем, чтобы их работа не была полностью потеряна
  • Вы знаете, на каком этапе произошел сбой. Отмените этот шаг, то есть выбросьте объекты / данные и вернитесь к точке перед исключением.
  • Восстановите данные, введенные пользователем со второй точки, чтобы им не нужно было повторять действия заново.

Дело в том, что ваша программа может вернуться в правильное состояние.

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