суббота, 16 мая 2009 г.

Отключаем диалог вылета программы

Это перевод Disabling the program crash dialog. Автор: Реймонд Чен.

Если вы не хотите, чтобы ваша программа в случае вылета показывала бы стандартный диалог о вылете, то вы можете отключить его установкой флага SEM_NOGPFAULTERRORBOX для режима ошибок процесса (process error mode).

Наивным способом сделать это является вызов
SetErrorMode(SEM_NOGPFAULTERRORBOX);
но это полностью перезапишет предыдущий режим вместо того, чтобы изменить его! Другими словами, вы непреднамеренно выключаете и другие режимы!

К сожалению, в Windows нет функции GetErrorMode, поэтому вам придётся сделать двойной вызов:
var
Mode: DWord;
...
Mode := SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(Mode or SEM_NOGPFAULTERRORBOX);
Сначала мы устанавливаем новый режим (скорее всего, отключая любые другие уже установленные режимы), одновременно сохраняя предыдущий режим в переменную. Затем мы устанавливаем режим, добавляя флаг SEM_NOGPFAULTERRORBOX к предыдущему режиму, который мы сохранили в переменной.

Изменение существующего режима вмето его затирания очень важно. Например, предыдущий режим мог включать флаг SEM_NOALIGNMENTFAULTEXCEPT. Если вы случайно отключите его, ваша программа не будет больше получать автоматического исправления ошибок выравнивания и начнёт вылетать.

Однако, если вы посмотрите на документацию, вы увидите что флаг SEM_NOALIGNMENTFAULTEXCEPT является особым: система не даст вам выключить его, если он был уже включён. Почему? Потому что слишком много людей уже сделали эту же ошибку. Я помню, как раньше, до того, как мы ввели это правило, программы вылетали направо и налево, потому что они не делали двойной вызов, как в примере выше; в результате они стали вылетать при ошибках выравнивания (alignment faults). Поэтому и было добавлено это специальное правило. Добро пожаловать в мир совместимости приложений, где ответственность исправлений ошибок других людей ложится на операционную систему. Не забывайте, что дизайн функции SetErrorMode таков, что эту ошибку очень легко совершить.

Заметим, что режим ошибок - это настройка всего процесса, а не потока. Это означает, что изменение этого режима - это не та вещь, которую вы должны вот так легко менять, т.к. это может иметь неожиланные последствия для других потоков (которые вы можете и не контролировать). Для безопасности, программа должна устанавливать свой режим ошибок при запуске и не менять его потом.

Конечно, если вы отключите диалог о вылете программы, то вы также упустите возможность получать отчёты, генерируемые Windows Error Reporting, чтобы определить когда же ваша программа вылетает в реальных условиях.

2 комментария:

  1. Хорошего дня!
    Теперь Функция GetErrorMode появилась https://msdn.microsoft.com/en-us/library/windows/desktop/ms679355%28v=vs.85%29.aspx

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.

Примечание. Отправлять комментарии могут только участники этого блога.