Apple LLVM Compiler 3.0을 사용하고 -O3으로 컴파일 할 때 NSCoder와 함께 특이한 크래셔를 발견했습니다. 그것은 장치에서만 충돌합니다. iOS 5를 실행하는 iPhone 4, iOS 5를 실행하는 iPad 2 및 iOS 4를 실행하는 iPad 1을 테스트했습니다. 모든 충돌이 동일합니다.NSCoder의 decodeBytesForKey에 의해 반환 된 포인터를 참조 해제 할 때 iOS 장치에서 충돌이 발생했습니다.
-(id)initWithCoder:(NSCoder*)decoder
{
if (![super init])
{
return nil;
}
NSUInteger length = 0;
uint8_t* data = (uint8_t*)[decoder decodeBytesForKey:BBKey returnedLength:&length];
m_value = *(BBPointI32*)data;
return self;
}
을 그리고 여기에 BBPointI32이 작업은 다음과 같습니다 : 여기에 코드의 관련 섹션입니다 data
가 역 참조 될 때
typedef struct
{
NSInteger x;
NSInteger y;
}
BBPointI32;
EXC_BAD_ACCESS
발생합니다. 이것은 이 아니며 null 포인터 문제입니다. GDB를 첨부하면 길이가 8이고 sizeof (BBPointI)가 8이며 데이터가 정확한지 확인할 수 있습니다.
내가 해체 보면
, 충돌은에 무슨 일이 일어나고 : 잘 보이는ldrd r2, r3, [r0]
합니다. r0은 0xb546e를 포함하며, 주소는 data
입니다. 내가 그 기억을 조사 할 때, 나는 그것이 내가 기대하는 데이터를 포함하고 있음을 볼 수있다. 관심있는 사람에게는 r2에 72 개가 포함되어 있는지 (그 내용이 확실하지 않음) r3에 8 개가 포함되어 있습니다 (대부분 length
의 값).
누구든지이 문제에 관해 밝힐 수 있습니까?
고마워, 그 자리에있어. 이 문제는 컴파일러가'ldrd'를 사용하기로 결정한 것과 관련이 있습니다. ''BBPointI32 * '에'데이터'를 전송할 때 포인터가 제대로 정렬되었다는 것을 의미한다고 가정했으나 그렇지 않습니다. 그래서, 대신 : m_value = * (BBPointI32 *) data; 다음과 같이 사용해야합니다. memcpy (& m_value, data, length); –
@biorhythmist .. 그냥 들뜬 twitterer :) – ohhorob
나는 아주 비슷한 것을 경험하고 있습니다. iPad 3에서 발생하고 _not_ iPad 2에서 발생합니다! –