Что означает код исключения "EXC_I386_GPFLT"?

Что означает код исключения EXC_I386_GPFLT?

Знает ли его значение в зависимости от ситуации?

В этом случае я имею в виду тип исключения EXC_BAD_ACCESS с кодом исключения EXC_I386_GPFLT

Программа разработана в Xcode 5.0.1, посвященной cblas_zgemm() библиотеки BLAS. (Ну, я думаю, это не имеет значения...)

Большое спасибо!

4b9b3361

EXC_I386_GPFLT, безусловно, имеет в виду "Общая ошибка защиты", которая является способом x86, чтобы сказать вам, что "вы сделали то, что вам не разрешено делать". Это, как правило, НЕ означает, что вы получаете доступ к границам памяти, но может быть, что ваш код выходит за рамки и приводит к неправильному использованию кода/данных таким образом, который делает нарушение какой-либо защиты.

К сожалению, трудно понять, в чем проблема, без лишнего контекста, есть 27 различных причин, перечисленных в моем Руководстве по программированию AMD64, том 2 от 2005 г. - по всем счетам, вероятно, что через 8 лет добавил еще несколько.

Если это 64-разрядная система, вероятным сценарием является то, что ваш код использует "неканонический указатель" - это означает, что 64-разрядный адрес формируется таким образом, что верхние 16 бит адреса не все копии верхней части нижних 48 бит (другими словами, верхние 16 бит адреса должны быть 0 или все 1, на основе бит чуть ниже 16 бит). Это правило существует, чтобы гарантировать, что архитектура может "безопасно расширять количество действительных битов в диапазоне адресов". Это означало бы, что код либо перезаписывает некоторые данные указателя другим материалом, либо выходит за пределы при чтении некоторого значения указателя.

Другими вероятными причинами является несвязанный доступ с регистром SSE - другим словом, считывающим 16-байтовый регистр SSE с адресом, который не выравнивается по 16 байт.

Есть, как я уже сказал, многие другие возможные причины, но большинство из них связаны с тем, что "нормальный" код не будет выполняться в 32- или 64-разрядной ОС (например, загружать сегментные регистры с недопустимым индексом селектора или записи в MSR (специфичные для модели регистры)).

86
ответ дан 29 окт. '13 в 10:34
источник

Вы можете часто получать информацию из файлов заголовков. Например:

$ cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
$ find usr -name \*.h -exec fgrep -l EXC_I386_GPFLT {} \;
usr/include/mach/i386/exception.h
^C
$ more usr/include/mach/i386/exception.h
....
#define EXC_I386_GPFLT          13      /* general protection fault     */

ОК, так что это общая ошибка защиты (как ее название в любом случае предлагает). Googling "i386 общая ошибка защиты" дает много хитов, но этот выглядит интересным:

Защита памяти также реализуется с использованием дескрипторов сегмента. Во-первых, процессор проверяет, загружено ли значение в сегменте регистрирует ссылки действительным дескриптором. Затем он проверяет, что каждый линейный адрес, вычисленный фактически, лежит внутри сегмента. Так же тип доступа (чтение, запись или выполнение) проверяется на информацию в дескрипторе сегмента. Всякий раз, когда одна из этих проверок fail, исключение (прерывание) 13 (hex 0D). Это исключение называемый Общей защитой (GPF).

То, что 13 соответствует тому, что мы видели в файлах заголовков, так что это похоже на одно и то же. Однако из точки зрения программиста-программиста это означает, что мы ссылаемся на память, которой мы не должны быть, и на самом деле не имеет значения, как она реализована на оборудовании.

21
ответ дан 29 окт. '13 в 10:29
источник

Чтобы отладить и найти источник: Включите Zombies для приложения (Product\Scheme) и Launch Instruments, выберите Zombies. Запустите приложение в Xcode Затем перейдите к началу записи инструментов. Вернитесь в свое приложение и попробуйте создать ошибку. Инструменты должны обнаружить плохой вызов (зомби), если он есть.

Надеюсь, что это поможет!

19
ответ дан 30 апр. '15 в 15:46
источник

Я задавался вопросом, почему это появилось во время моих модульных тестов.

Я добавил объявление метода в протокол, который включал throws; но метод потенциального выброса даже не использовался в этом конкретном тесте. Включение Zombies в тест звучало как слишком много проблем.

Оказывается, ⌘K clean сделал трюк. Я всегда обманываю, когда это решает актуальные проблемы.

12
ответ дан 10 окт. '15 в 16:44
источник

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

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

0
ответ дан 09 авг. '18 в 22:06
источник

У меня было похожее исключение на Swift 4.2. Я потратил около получаса, пытаясь найти ошибку в своем коде, но проблема исчезла после закрытия Xcode и удаления папки производных данных.

0
ответ дан 13 дек. '18 в 19:35
источник

В моем случае ошибка была выдана в Xcode при запуске приложения на симуляторе iOS. Хотя я не могу ответить на конкретный вопрос "что означает ошибка", я могу сказать, что помогло мне, может быть, это также поможет другим.

Решением для меня было Erase All Content and Settings в симуляторе и Clean Build Folder... в Xcode.

0
ответ дан 13 июня '18 в 23:50
источник