Почему исключение из одного потока приводит к сбою всей программы (как это предотвратить?) - PullRequest
1 голос
/ 22 сентября 2019

При запуске, например,

int x = *(0x00000);

Программа вылетает.Но почему происходит сбой всей программы вместо одного потока?Я создал несколько потоков, которые просто спят непрерывно, чтобы проверить это.Есть ли способ сделать только текущий поток, а не всю программу (на окнах, использующих winapi)?

Спасибо.

1 Ответ

1 голос
/ 22 сентября 2019

Но почему происходит сбой всей программы, а не одного потока?

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

по той же причине - если необработанное исключение было в режиме ядра - система завершает сам и пытается создать BSOD.потому что после необработанного исключения в ядре - вся система в нестабильном состоянии.и просто прервать глючный поток - не решение.

Есть ли какой-нибудь способ сделать только текущий поток, а не всю программу (на окнах, использующих winapi)?

формально да.и просто - вы можете установить UnhandledExceptionFilter с помощью SetUnhandledExceptionFilter функции и внутри UnhandledExceptionFilter просто позвоните TerminateThread для текущегопоток (GetCurrentThread()), потому что

Обработчик исключений, указанный в lpTopLevelExceptionFilter, выполняется в контексте потока, вызвавшего ошибку.

Также обратите внимание, что этот обратный вызов вызывается, только если процесс не отлаживается.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...