Как установить новый обработчик / ответчик для аварий EXC_BAD_ACCESS - PullRequest
0 голосов
/ 07 января 2019

Я ищу способы переопределить ответчик / обработчик для EXC_BAD_ACCESS. Вот как я установил обработчик для signal сбоев или NSException, который работает нормально:

NSSetUncaughtExceptionHandler(newExceptionHandler)
signal(SIGABRT, newSignalHandler)
signal(SIGILL, newSignalHandler)

Я попробовал это, но это не вызывается:

signal(EXC_BAD_ACCESS, newSignalHandler)

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Как упоминает Карл, перехват событий сбоя на iOS (и macOS) чреват опасностью по разным причинам. Некоторое время я был сопровождающим Crashlytics SDK, и я бы настоятельно рекомендовал не делать этого.

Но, это определенно возможно.

Одна вещь, которая, кажется, волнует людей, - это связь между сигналами, исключениями (ObjC или C ++) и мах исключениями. Это все очень разные вещи.

В iOS (и в tvOS, macOS) события, завершающие процесс, Mach исключения . Это события низкого уровня, которые вы можете перехватить. Когда вы видите этот префикс EXC_, вы знаете, что смотрите на исключение маха. Я считаю, что все они определены в mach/exception.h.

Теперь в iOS есть интересная реализация, где, если нет обработчиков исключений маха, ОС преобразует событие в сигнал Unix. Функция signal может использоваться для их перехвата. Поскольку EXC_BAD_ACCESS не является unix-сигналом, он не является допустимым аргументом для функции signal. Но вы можете добавить обработчики к перечисленным сигналам, и они будут давать вам примерно ту же информацию.

Исключения Маха являются значительно более мощным и безопасным механизмом для перехвата таких событий. К сожалению, они также требуют значительно более сложной системы обработки. Сигналы имеют всевозможные проблемы, но их намного проще использовать.

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

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

0 голосов
/ 07 января 2019

Если вы не используете существующий аварийный репортер (их очень трудно написать самостоятельно, когда имеешь дело с поврежденной памятью и т. П.), Вы можете обратиться к их источникам, чтобы узнать, какие сигналы они обрабатывают. Например, PLCrashReporter's PLCrashReporter.m подключается к SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV и SIGTRAP, что, кажется, является обычным списком для обработчиков сбоев. EXC_BAD_ACCESS должен превратиться в SIGBUS или SIGSEGV. Правильное написание повторно входящего кода в обработчиках сигналов чрезвычайно сложно (там не может использоваться ни ObjC, ни большинство API-интерфейсов C), поэтому будьте осторожны - хотя я полагаю, что если у вас уже происходит сбой, можете не навреди. Но чем внимательнее вы будете, тем больше исключений вы будете обрабатывать без сбоев.

...