2011-01-31 3 views
4

EDIT :이 충돌의 원인을 발견했습니다! bbum는 버퍼 오버 플로우가 이것에 대한 매우 일반적인 원인임을 지적, 그래서 나는 내가 가진 유일한 버퍼 유형의 malloc을 바라 보았다 :과도하게 릴리스 된 개체 디버깅, NSZombie의 문제

closedList = (AINavigationCell **)malloc(baseCells.count * sizeof(AINavigationCell *)); 

나중에보다 훨씬 더 있었어야 배열의 경계, 과거 데이터를 덮어되었다 baseCells.count. 고마워요.

질문 : 내가 개체를 해제 이상 - 나는 것을 나타내는 것 같다가 재생 될 EXC_BAD_ACCESS 동안 NSAutoreleasePool이 5V를 가지고있다. 그래서 NSZombie을 사용할 수 있지만 프로그램이 더 이상 충돌하지 않습니다. 콘솔에 어떤 정보도 기록되지 않습니다. NSZombie를 끄면 충돌이 다시 발생합니다. 이것의 의미는 무엇입니까? NSZombies가 이런 종류의 문제를 해결하는 데 사용되었다고 생각했습니다. NSZombie가 도움이되지 않는다면,이 over-release 객체를 조사 할 다른 방법이 있습니까?

또한 시뮬레이터에서 크래시가 재생성되지 않아 NSZombie에서 Instruments를 사용할 수 없습니다.

폴로 우잉은 충돌 지점에서 백 트레이스입니다.

#0 0x31ac8bc8 in _cache_fill() 
#1 0x31acaf8e in lookUpMethod() 
#2 0x31ac8780 in _class_lookupMethodAndLoadCache() 
#3 0x31ac859a in objc_msgSendSuper_uncached() 
#4 0x328014f0 in -[__NSArrayReverseEnumerator dealloc]() 
#5 0x327b1f7a in -[NSObject(NSObject) release]() 
#6 0x327b63c8 in CFRelease() 
#7 0x327b58de in _CFAutoreleasePoolPop() 
#8 0x320e132c in NSPopAutoreleasePool() 
#9 0x30899048 in CAPopAutoreleasePool() 
#10 0x30902784 in CA::Display::DisplayLink::dispatch() 
#11 0x309027ea in CA::Display::IOMFBDisplayLink::callback() 
#12 0x30076bfa in IOMobileFramebufferVsyncNotifyFunc() 
#13 0x333dee6a in IODispatchCalloutFromCFMessage() 
#14 0x327e8be6 in __CFMachPortPerform() 
#15 0x327e06fe in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__() 
#16 0x327e06c2 in __CFRunLoopDoSource1() 
#17 0x327d2f7c in __CFRunLoopRun() 
#18 0x327d2c86 in CFRunLoopRunSpecific() 
#19 0x327d2b8e in CFRunLoopRunInMode() 
#20 0x3094a4aa in GSEventRunModal() 
#21 0x3094a556 in GSEventRun() 
#22 0x32c14328 in -[UIApplication _run]() 
#23 0x32c11e92 in UIApplicationMain() 
#24 0x00002556 in main (argc=1, argv=0x2fdff660) at /Users/hyn/Desktop/MyProject-trunk/main.m:14 

답변

16

설명하는 문제는 몇 가지 중 하나 일 수 있습니다. 개체가 너무 많이 풀리거나 메모리가 손상되었을 수 있습니다. 메모리를 손상 시키면 객체의 처음 몇 바이트를 손상 시키며 특히 자동 릴리즈 풀 드레인 (또는 다른 메시지) 중에 충돌로 쉽게 나타납니다.

시뮬레이터가 아닌 장치에서 충돌이 발생해도 메모리 손상을 지적합니다. 장치 [ARM]와 시뮬레이터 [i386]의 아키텍처는 매우 다르며 여러 가지 문제가있을 수 있습니다.

일반적으로 매우 일관되게 나타나지는 않습니다.

먼저 충돌의 백 트레이스를 게시하십시오. 도움이 될 수도 있습니다.

둘째로, 어떤 종류의 원시 malloc 전화를합니까? 또는 버퍼에 데이터를 채우고 있습니까? 이러한 충돌의 가장 일반적인 원인은 버퍼의 끝을지나갑니다.


#0 0x31ac8bc8 in _cache_fill() 
#1 0x31acaf8e in lookUpMethod() 
#2 0x31ac8780 in _class_lookupMethodAndLoadCache() 
#3 0x31ac859a in objc_msgSendSuper_uncached() 
#4 0x328014f0 in -[__NSArrayReverseEnumerator dealloc]() 

(영업이 문제를 해결하지만, 이후 위가 추가되었습니다 - 아카이브에 대한)

그 충돌 추적 메모리 손상의 고전 서명입니다. 즉, isa 포인터 (인스턴스의 클래스를 가리키는 객체의 첫 번째 포인터의 바이트)가 발동되었습니다. 이것은 일반적으로 객체가 전에 에있는 메모리 버퍼를 오버런 할 때 발생합니다. 단지 2 바이트 오버런이라면, 다른 플랫폼 간의 동작은 malloc 퀀 타이지 - 할당의 실제 크기 (하나의 플랫폼에서 90 바이트를 요구하면 96을 얻을 수 있기 때문에)와 다를 수 있습니다. 또 다른 128 개 - - 플랫폼 간 차이점, 심지어 릴리스 간 차이.

특히 isa는 런타임에서 가비지 값을 역 참조 한 포인터와 비슷한 값으로 스톰되고 결과 위치를 클래스의 메서드 테이블로 처리하려고했습니다.

objc_msgSend*() 함수 중 하나에 몇 프레임 깊이 충돌이 발생할 때마다 메모리 손상 가능성이 크며, 그렇다면 거의 항상 버퍼 오버플로가 발생합니다.

하기가 쉽기 때문에 좀비 감지 기능을 사용하여 테스트 패스를 작성하여 "때로는 사실 과장된 경우"를 잡는 것이 좋습니다.

+1

귀하의 제안은 맞았습니다. 버퍼 오버 플로우 문제가 발생했습니다. 시간을 절약 해 주셨고, 며칠간 디버깅을 하셨을 수도 있습니다. 그리고 나는 존재하지 않았던 과도한 거래를 열심히 찾고있었습니다. 정말 고맙습니다. – Morrowless

+0

대단히 환영합니다. – bbum

+0

bbum 시연은 굉장하지만 또 다시! :-) – Dad