programing tip

예외 코드“EXC_I386_GPFLT”의 의미는 무엇입니까?

itbloger 2020. 7. 29. 07:52
반응형

예외 코드“EXC_I386_GPFLT”의 의미는 무엇입니까?


예외 코드의 의미는 무엇입니까 EXC_I386_GPFLT?

상황에 따라 그 의미가 달라 집니까?

이 경우 EXC_BAD_ACCESS예외 코드 가있는 예외 유형 참조 하고 있습니다.EXC_I386_GPFLT

이 프로그램은 cblas_zgemm()BLAS 라이브러리를 다루는 Xcode 5.0.1에서 개발되었습니다 . (잘 모르겠습니다.)

대단히 감사합니다!


EXC_I386_GPFLT는 "일반적인 보호 오류"를 참조하고 있습니다. "일반적인 보호 오류"는 x86이 "허용되지 않은 일을했다"는 것을 알려주는 방법입니다. 일반적으로 메모리 범위를 벗어난 액세스를 의미하지는 않지만 코드가 범위를 벗어 났으며 일종의 보호 위반을 일으키는 방식으로 잘못된 코드 / 데이터가 사용되는 것일 수 있습니다.

불행히도 문제가없는 상황을 정확히 파악하기 어려울 수 있습니다. 2005 년부터 AMD64 프로그래머 매뉴얼, Vol 2에 27 가지 원인이 나와 있습니다. 모든 계정에 의해 8 년 후 더.

64 비트 시스템 인 경우, 그럴듯한 시나리오는 코드가 "정규적이지 않은 포인터"를 사용한다는 것입니다. 즉, 주소의 상위 16 비트가 아닌 방식으로 64 비트 주소가 형성됩니다. 하위 48 비트의 최상위 복사본 (즉, 주소의 상위 16 비트는 16 비트 바로 아래의 비트를 기준으로 모두 0 또는 모두 1이어야 함) 이 규칙은 아키텍처가 "주소 범위에서 유효한 비트 수를 안전하게 확장"할 수 있도록하기위한 것입니다. 이것은 코드가 다른 포인터 데이터로 다른 포인터 데이터를 덮어 쓰거나 일부 포인터 값을 읽을 때 범위를 벗어 났음을 나타냅니다.

또 다른 원인은 SSE 레지스터와의 정렬되지 않은 액세스, 즉 16 바이트로 정렬되지 않은 주소에서 16 바이트 SSE 레지스터를 읽는 것입니다.

내가 말했듯이, 가능한 다른 많은 이유가 있지만, 대부분의 "정상적인"코드가 32 비트 또는 64 비트 OS에서 수행하지 않는 것들 (예 : 잘못된 선택기 인덱스를 사용하여 세그먼트 레지스터로드 또는 쓰기) 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 (16 진 0D)이 발생합니다. 이 예외를 GPF (General Protection Fault)라고합니다.

그것은 13우리가 헤더 파일에서 본 것과 일치하므로 같은 것 같습니다. 그러나 응용 프로그램 프로그래머의 관점에서 볼 때 우리가해서는 안되는 메모리를 참조한다는 의미이며 하드웨어에서 어떻게 구현되는지는 중요하지 않습니다.


소스를 디버그하고 찾으려면 앱 (Product \ Scheme)에 좀비를 활성화하고 인스트루먼트를 시작하십시오. 좀비를 선택하십시오. Xcode에서 앱을 실행 한 다음 Instruments의 기록 시작으로 이동하십시오. 앱으로 돌아가서 오류를 생성 해보십시오. 계측기는 잘못된 호출 (좀비로)이있는 경우이를 감지해야합니다.

그것이 도움이되기를 바랍니다!


이것이 왜 단위 테스트 중에 나타 났는지 궁금했습니다.

프로토콜에 메소드 선언을 추가했습니다 throws. 그러나 잠재적으로 던지는 방법은 특정 테스트에서 사용되지 않았습니다. 테스트에서 좀비를 활성화하면 너무 많은 문제가 발생했습니다.

⌘K clean이 트릭을 수행 한 것으로 나타났습니다. 나는 그것이 실제 문제를 해결할 때 항상 열광적입니다.


Swift 4.2에서도 비슷한 예외가있었습니다. 내 코드에서 버그를 찾으려고 30 분 정도 걸렸지 만 Xcode를 닫고 파생 데이터 폴더를 제거한 후에 문제가 발생했습니다. 바로 가기는 다음과 같습니다.

rm -rf ~/Library/Developer/Xcode/DerivedData

필자의 경우 iOS 시뮬레이터에서 앱을 실행할 때 Xcode에서 오류가 발생했습니다. "오류가 무엇을 의미하는지"라는 특정 질문에 대답 할 수는 없지만, 나에게 도움이 된 것을 말할 수 있습니다.

나를위한 해결책 Erase All Content and Settings은 시뮬레이터와 Clean Build Folder...Xcode에있었습니다.


이것은 Xcode가 두 개의 다른 클래스에서 동일한 변수 이름을 사용하는 것처럼 보이지 않았기 때문에 발생했습니다 (변수 이름은 프로토콜과 관련이 없지만 동일한 프로토콜을 준수하는 동일한 프로토콜을 준수 함). 새 변수의 이름을 바 꾸었습니다.

디버깅하는 동안 그것을 보려고 충돌하는 세터로 들어가야했습니다. 이 답변은 iOS에 적용됩니다


오류가가 정의하는 폐쇄 내부에 발생하는 경우 selfunowned, 당신은 당신이 액세스 할 수있는 제한 될 수 있으며, 특정 상황에서이 오류 코드를 받게됩니다. 특히 디버깅하는 동안. 이 경우에 변경 [unowned self]시도하십시오[weak self]


이 작업을 수행하는 동안이 오류가 발생했습니다.

 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

참고 URL : https://stackoverflow.com/questions/19651788/whats-the-meaning-of-exception-code-exc-i386-gpflt

반응형