Znalazłem nietypowy przerywacz z NSCoder podczas korzystania z kompilatora Apple LLVM 3.0 i skompilowany z opcją -O3. To tylko zawiesza się na urządzeniach. Przetestowałem iPhone'a 4 z systemem iOS 5, iPada 2 z systemem iOS 5 i iPadem 1 z systemem iOS 4. Wszystkie awarie są identyczne. Oto odpowiedni fragment kodu:Awaria na urządzeniu z systemem iOS podczas usuwania odwołania do wskaźnika zwróconego przez dekodowanie identyfikatora NSCoderBodesForKey
-(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;
}
A oto co BBPointI32 jest:
typedef struct
{
NSInteger x;
NSInteger y;
}
BBPointI32;
EXC_BAD_ACCESS
się dzieje, gdy data
jest dereferencjonowane. Jest to , a nie problem z pustym wskaźnikiem. Jeśli dołączę GDB, widzę, że długość wynosi 8, sizeof (BBPointI) to także 8, a dane są poprawne.
Jeśli patrzę na demontażu, katastrofa dzieje się na:
ldrd r2, r3, [r0]
który wygląda dobrze. r0 zawiera 0xb546e, który jest adresem data
. Kiedy sprawdzam tę pamięć, widzę, że zawiera ona dane, których się spodziewam. Dla każdego, kto jest zainteresowany, r2 zawiera 72 (nie jestem pewien co to jest), a r3 zawiera 8 (prawdopodobnie wartość length
).
Czy ktoś może rzucić trochę światła na tę kwestię?
Dzięki, to jest na miejscu. Problem * był * związany z decyzją kompilatora o użyciu 'ldrd'. Kiedy przesyłam 'dane' do' BBPointI32 *', zakładałem, że oznaczało to, że wskaźnik był prawidłowo wyrównany, ale tak nie było. Tak więc zamiast: m_value = * (BBPointI32 *) dane; Potrzebowałem użyć: memcpy (& m_value, dane, długość); –
@ robothythmist .. nie tylko przezabawny twitterer :) – ohhorob
Mam coś bardzo podobnego. Zdarza się na iPadzie 3 i _nie_ na iPadzie 2! –