Либо мой отладчик сломан, либо есть что-то фундаментальное, чего я не понимаю.
У меня есть очень простой код в очень простой программе командной строки, которая должна авария. Однако это не приводит к сбою.
int main (int argc, const char * argv[])
{
NSString *string = [[NSString alloc] initWithString:@"Hello"];
[string release];
NSLog(@"Length: %d", [string length]);
return 0;
}
Оператор журнала печатает «Длина: 5», как и следовало ожидать от действительной строки. Тем не мение, строка должна быть освобождена к этому моменту, и должна появиться ошибка exec_bad_access
.
Я пробовал этот код с подключенным отладчиком и без подключенного отладчика - оба дают одинаковый результат. Я также включил (и отключил) NSZombie
, который, похоже, не имеет никакого эффекта (сначала я думал, что это проблема, поскольку объекты NSZombie
никогда не освобождаются - но он все равно не дает сбой с NSZombie
отключено).
У меня есть точки останова, установленные в моем локальном файле .gdbinit
, чтобы нарушать такие вещи, как - [NSException raise]
и ] objc_exception_throw
. У меня также установлены точки останова для многих методов на NSZombie
, чтобы их поймать.
fb -[NSException raise]
fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
#define NSZombies
# this will give you help messages. Set to NO to turn them off.
set env MallocHelp=YES
# might also be set in launch arguments.
set env NSZombieEnabled=YES
set env NSDeallocateZombies=NO
set env MallocCheckHeapEach=100000
set env MallocCheckHeapStart=100000
set env MallocScribble=YES
set env MallocGuardEdges=YES
set env MallocCheckHeapAbort=1
set env CFZombie 5
fb -[_NSZombie init]
fb -[_NSZombie retainCount]
fb -[_NSZombie retain]
fb -[_NSZombie release]
fb -[_NSZombie autorelease]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie forwardInvocation:]
fb -[_NSZombie class]
fb -[_NSZombie dealloc]
fb szone_error
fb objc_exception_throw
С этими установленными точками останова и включенным NSZombie, Я должен получить что-то вроде [NSString length]: сообщение, отправленное на освобожденный экземпляр 0x100010d39
, напечатанное на консоли, но я этого не вижу. Я вижу NSLog
, печатающий длину как 5.
Я вижу аналогичное поведение с другими классами, такими как NSURL
и NSNumber
. Но некоторые классы аварийно завершают работу, как и ожидалось, например NSError
и NSObject
.
Имеет ли это какое-то отношение к кластерам классов? Разве они не следуют тем же правилам в отношении управления памятью?
Если кластеры классов не связаны с этой проблемой, единственной другой общей чертой, которую я мог видеть, было то, что классы, которые не дают сбоев таким образом, являются платными. бесплатный мост с аналогом Core Foundation. Может ли это иметь какое-то отношение?