Что означает код исключения "EXC_I386_GPFLT"?
Что означает код исключения EXC_I386_GPFLT
?
Его значение зависит от ситуации?
В этом случае я имею в виду тип исключения EXC_BAD_ACCESS
с кодом исключения EXC_I386_GPFLT
Программа разработана в Xcode 5.0.1, занимается cblas_zgemm()
библиотеки BLAS.(Ну, я думаю, это не имеет значения...)
Большое спасибо!
18 ответов
EXC_I386_GPFLT, безусловно, ссылается на "Ошибка общей защиты", которая является способом x86, чтобы сказать вам, что "вы сделали то, что вам запрещено делать". Как правило, это не означает, что вы получаете доступ за пределы памяти, но может случиться так, что ваш код выходит за пределы и приводит к тому, что неверный код / данные используются таким образом, что нарушает защиту какого-либо рода.
К сожалению, может быть трудно точно определить, в чем заключается проблема, без какого-либо контекста, в моем Руководстве для программиста AMD64, том 2 от 2005 года, перечислены 27 различных причин - по всей вероятности, через 8 лет было бы добавлено несколько Больше.
Если это 64-битная система, вероятным сценарием является то, что ваш код использует "неканонический указатель" - это означает, что 64-битный адрес сформирован таким образом, что старшие 16 битов адреса не являются все копии верхней части нижних 48 битов (другими словами, все верхние 16 битов адреса должны быть равны 0 или всем 1, основываясь на битах чуть ниже 16 бит). Это правило действует, чтобы гарантировать, что архитектура может "безопасно расширять количество допустимых битов в диапазоне адресов". Это будет означать, что код либо перезаписывает некоторые данные указателя другими вещами, либо выходит за пределы при чтении некоторого значения указателя.
Другой вероятной причиной является не выровненный доступ с регистром SSE - другими словами, чтение 16-байтового регистра SSE с адреса, который не выровнен по 16 байтов.
Как я уже говорил, существует множество других возможных причин, но большинство из них связаны с тем, что "нормальный" код не будет выполнять в 32- или 64-разрядной ОС (например, загрузка регистров сегментов с неверным индексом селектора или запись в MSR (типовые регистры)).
Вы часто можете получить информацию из заголовочных файлов. Например:
$ 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
соответствует тому, что мы видели в заголовочных файлах, так что это выглядит так же. Однако, с точки зрения разработчика приложений, это просто означает, что мы ссылаемся на память, которой мы не должны быть, и на самом деле не имеет значения, как это реализовано на оборудовании.
Для отладки и поиска источника: включите зомби для приложения (продукт \ схема) и запустите инструменты, выберите зомби. Запустите ваше приложение в XCode, затем перейдите в Инструменты, чтобы начать запись. Вернитесь в приложение и попробуйте сгенерировать ошибку. Инструменты должны обнаруживать плохой вызов (зомби), если он есть.
Надеюсь, поможет!
Я удивился, почему это появилось во время моих юнит-тестов.
Я добавил объявление метода в протокол, который включал throws
; но потенциально бросающий метод даже не использовался в этом конкретном тесте. Включение зомби в тесте звучало как слишком большая проблема.
Оказывается, cleanK чистые сделали свое дело. Я всегда ошеломлен, когда это решает актуальные проблемы.
У меня было похожее исключение на Swift 4.2. Я потратил около получаса, пытаясь найти ошибку в своем коде, но проблема исчезла после закрытия Xcode и удаления папки производных данных.
В моем случае ошибка была выдана в Xcode при запуске приложения на симуляторе iOS. Хотя я не могу ответить на конкретный вопрос "что означает ошибка", я могу сказать, что помогло мне, может быть, это также поможет другим.
Решение для меня было Erase All Content and Settings
в симуляторе и до Clean Build Folder...
в Xcode.
В моем случае я не использовал правильный заполнитель вformat
параметрString.localizedStringWithFormat
:
let format = "I have an %s."
let string = "exception"
String.localizedStringWithFormat(format, string)
изменение%s
к%@
решил проблему.
У меня возникла эта проблема при выходе из представления (вернуться к предыдущему представлению).
причина была в том, что
addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
view.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
view.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
view.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
view.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
])
+ Изменить safeAreaLayoutGuide
к self
решить вопрос.
Значение выравнивает представление с ведущим, конечным, верхним, нижним супервизором вместо безопасной области)
Я вижу этот код ошибки при сбое ротации в Xcode 12.0 Beta 6, только в симуляторе iOS 14. Однако на моем реальном устройстве под управлением iOS 13 сбой не происходит! Поэтому, если вы запускаете бета-версию и видите сбой вращения в симуляторе, возможно, вам просто нужно запустить на реальном устройстве с небета-версией iOS.
Старый вопрос. Не так много вещей, связанных с Objective-C, поэтому я добавлю свою копейку. Может кому-то помочь.
Имел типичный EXC_BAD_ACCESS и боролся с тем, что его вызывало.
После некоторого размышления я обнаружил, что это было вызвано тем, что мой код ссылался на переменную внутри блока, которая была определена вне блока и не использовала префикс __block. И упомянутая переменная передавалась вызову метода внутри блока и определялась как автоматически освобождаемый параметр.
Трудно объяснить словами. Итак, пример = код для удаления клиентов в массиве, который я перечислял с помощью блока. передается «ошибка». Затем я передаю это методу, вызываемому в блоке. Значение параметра error изменяется при вызове метода. Затем я пытаюсь обратиться к этому за пределами блока. И вот когда я получаю плохой доступ. Возможно, это немного не связано с вопросом ОП, но поиск проблемы поместил меня на эту страницу, и кто-то еще может найти это полезным.
- (BOOL)deleteCustomer:(CHCustomer *)customer
error:(NSError *__autoreleasing*)error {
__block BOOL success = YES;
NSMutableArray *customerOrders = [self ordersForCustomer:customer
error:error];
if ([customerOrders count] > 0) {
[customerOrders enumerateObjectsUsingBlock:^(id obj,
NSUInteger idx,
BOOL *stop) {
CHOrderHeader *orderHeader = (CHOrderHeader *)obj;
if (![self deleteOrderForOohSeqNo:[orderHeader oohSeqNo]
preserveExistingPhotoKeys:NO
error:error]) {
*stop = YES;
success = NO;
}
}]; // enumerateObjectsUsingBlock
}
// EXC_BAD_ACCESS occurred on line below:
NSLog(@"Is this an NSError? %@", [*error class]);
return success;
}
Я мог бы получить эту ошибку, работая с
UnsafeMutablePointer
let ptr = rawptr.assumingMemoryBound(to: A.self) //<-- wrong A.self Change it to B.Self
ptr.pointee = B()
Я получил эту ошибку при этом:
NSMutableDictionary *aDictionary=[[NSMutableDictionary alloc] initWithObjectsAndKeys:<#(nonnull id), ...#>, nil]; //with 17 objects and keys
Он исчез, когда я вернулся к:
NSMutableDictionary *aDictionary=[[NSMutableDictionary alloc] init];
[aDictionary setObject:object1 forKey:@"Key1"]; //17 times
В моем случае
EXC_I386_GPFLT
было вызвано отсутствием возвращаемого значения в получателе свойства. Как это:
- (CppStructure)cppStructure
{
CppStructure data;
data.a = self.alpha;
data.b = self.beta;
return data; // this line was missing
}
Xcode 12.2
Моя проблема заключалась в глупой игровой площадке Xcode. Детская площадка была для меня нестабильной с тех пор, как она появилась много лет назад, Apple так запуталась.
Удаление производных данных и т. Д. Не помогло, единственный способ заставить мой код не генерироваться - это запустить его в проекте приложения.
Если ошибка выбрасывается внутри замыкания, которое определяет self
как unowned
вы можете быть ограничены в доступе и получите этот код ошибки в определенных ситуациях. Особенно во время отладки. Если это так, попробуйте изменить [unowned self]
в [weak self]
Я видел ту же ошибку на Swift/iOS. В моем случае это было потому, что я пытался начать
(NS)Operation
непосредственно используя его
start()
функция. Но вместо этого мне нужно было передать его
OperationQueue
. Что-то вроде этого
var queue = OperationQueue(); queue.addOperation(myOperation)
Это произошло со мной, потому что XCode, кажется, не нравился мне, используя одно и то же имя переменной в двух разных классах (которые соответствуют одному и тому же протоколу, если это имеет значение, хотя имя переменной не имеет никакого отношения к любому протоколу). Я просто переименовал мою новую переменную.
Мне пришлось войти в сеттеры, где он падал, чтобы увидеть его во время отладки. Этот ответ относится к iOS
Для меня это проблема, связанная с раскадровкой, есть возможность сборки ViewController для iOS 9.0 и более поздних версий, ранее установленных для iOS 10.0 и более поздних версий. На самом деле я хочу понизить версию с 10 до iOS 9.3.