it-swarm.com.ru

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

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

Его значение зависит от ситуации?

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

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

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

91
Lewen

EXC_I386_GPFLT, безусловно, ссылается на «Ошибка общей защиты», которая является способом x86, чтобы сказать вам, что «вы сделали то, что вам запрещено делать». Как правило, это не означает, что вы обращаетесь за пределы памяти, но может случиться так, что ваш код выходит за пределы и приводит к тому, что неверный код/​​данные используются таким образом, что нарушает защиту какого-либо рода. 

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

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

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

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

93
Mats Petersson

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

$ 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     */

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

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

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

22
trojanfoe

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

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

20
Khalid Mammadov

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

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

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

12
ctietze

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

4
Stanislau Baranouski

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

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

0
Manuel

Если ошибка возникает внутри замыкания, которое определяет self как unowned, вы можете быть ограничены в доступе и получите этот код ошибки в определенных ситуациях. Особенно во время отладки. Если это так, попробуйте изменить [unowned self] на [weak self]

0
Matjan

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

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

0
Stephen J