Как завершить процесс в Windows-7, не открывая диалоговое окно WER?

Возможно ли аварийное завершение обычного процесса в пользовательском режиме в Windows-7 без диалогового окна Windows Error Reporting (WER)? (Когда и если WER обычно включен и никакие определенные флаги не применяются.)

Примечание. Меня не интересует отключение WER, меня интересуют сценарии сбоя, при которых WER не запускается, хотя это должно произойти, и Windows "молча" завершает работу приложения.

В Windows XP довольно просто написать приложение на C или C++ (в пользовательском режиме), которое портит свое собственное адресное пространство таким образом, что, когда наконец нарушается Access Access (или другое необработанное исключение Win32), Windows XP будет просто молча прекратить процесс, не сообщая пользователю вообще:

...
void stackbreaker() {
    printf("%s\n", __FUNCTION__);
    // global/static buffer
    static char buf[128] = "In a hole in the ground there lived a hobbit. And it burrowed through your stack. It even built a round door into you function.";
    // Get address on the stack
    char local;
    char* stack = &local;
    // nuke the stack:
    memcpy(stack - 64, buf, sizeof(buf));
    // Kaboom. No user defined unhandled exception filter will be called. Stack nuked.
    // Process will terminate silently on Windows XP.
    // But on Windows-7 you still get the WER dialog.
}
...

Вызов вышеуказанной функции в простом проекте C++ (в режиме выпуска - следите за оптимизацией компилятора при тестировании - и не запускайте под отладчиком):

  • Молча прекратить процесс, под XP.
  • Отобразить диалоговое окно сбоя WER под Windows-7.
  • В сторону: ни при каких обстоятельствах он не будет вызывать ваш собственный фильтр необработанных исключений, даже если вы установили его через SetUnhandledExceptionFilter

Что меня сейчас интересует, так это то, реализован ли в Windows 7 механизм WER таким образом, что я всегда получаю диалоговое окно с сообщением об ошибке[a] в моем приложении, или существуют ли сценарии повреждения процесса даже в Windows 7, что предотвратит появление диалога WER?


Я добавлю немного чтения, которое я сделал:

В книге " Windows через C/C++" (5-е изд. Рихтера, Насарре) они описывают, что происходит в "процессе сбоя" (стр. 711):

  1. Фильтры исключений.
  2. ...
  3. ...
  4. ядро обнаруживает необработанное исключение
  5. блокировка вызова ALPC к Wer Service
  6. WER отчетности вступает в силу.
  7. ...

Теперь они указывают на то, что Win7 делает это не так, как Windows XP (цитирую эту книгу, стр. 710:)

... Начиная с Windows Vista, UnhandledExceptionFilter функция больше не отправляет отчет об ошибках на серверы MS. Вместо. Ядро обнаруживает, что исключение не обрабатывается потоком пользовательского режима (Шаг 4)...

Таким образом, это может означать, что у процесса нет никакого способа "аварийно завершить работу" - в Vista и выше - таким образом, чтобы предотвратить включение WER. Я пытаюсь подтвердить или опровергнуть это.


[a]: Очевидно, что процесс можно легко "убить" без каких-либо следов, вызвав один из различных *exit или же terminate* функции. Вопрос заключается в том, если вы можете исключить такую ​​причину прекращения, (как) возможно ли "сбить" процесс пользовательского режима на Win7 таким образом, чтобы предотвратить отображение диалога WER.

2 ответа

Решение

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

В Vista и более поздних версиях он работает внешне в аварийном потоке. Кроме того, само ядро ​​отвечает за уведомление WER о сбое процесса (с помощью расширенного вызова локальной процедуры).

Согласно Windows Internals, эти изменения решают проблему исчезающего процесса. Я могу только поверить им на слово. Очевидно, что если служба WER сама повреждена (или остановлена), вы все равно получите тихие сбои.

РЕДАКТИРОВАТЬ

Из Windows Internals, 5-е издание, стр. 122:

До Windows Vista все операции [WER], которые мы описывали, должны были происходить в контексте сбойного потока... При определенных типах сбоев... сам фильтр необработанного исключения зависал. Этот "тихий процесс смерти" нигде не регистрировался. ... Windows Vista и более поздние версии улучшили механизм WER, выполняя эту работу извне из аварийного потока, если происходит сбой самого фильтра необработанных исключений.

Страница 124:

... все процессы Windows теперь имеют порт ошибки, который фактически является объектом порта ALPC, зарегистрированным службой WER. Ядро... будет использовать этот порт для отправки сообщения службе WER, которая затем проанализирует процесс сбоя.... Это решает все проблемы тихого процесса смерти...

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

UINT WINAPI SetErrorMode(_In_  UINT uMode);

SEM_NOGPFAULTERRORBOX 0x0002 Система не отображает диалоговое окно отчетов об ошибках Windows.

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

Кроме того, начиная с Windows 7:

BOOL SetThreadErrorMode(
  _In_   DWORD dwNewMode,
  _Out_  LPDWORD lpOldMode
);

Некоторые программы и dll-ы используют эти функции, чтобы скрыть ошибки от пользователя.

Другие вопросы по тегам