[iphone] malloc “double free”오류의 원인을 찾는 방법은 무엇입니까?

Objective-C에서 응용 프로그램을 프로그래밍하고 있는데이 오류가 발생합니다.

MyApp (2121,0xb0185000) malloc : *** 개체 0x1068310에 대한 오류 : 이중 해제
*** malloc_error_break에서 중단 점을 디버그로 설정

NSAutoreleasePool을 릴리스 할 때 발생하며 두 번 릴리스하는 개체를 파악할 수 없습니다.

그의 중단 점을 어떻게 설정합니까?

이 “개체 0x1068310″이 무엇인지 알 수있는 방법이 있습니까?



답변

디버거를 중단하면 객체가 무엇인지 알 수 있습니다. 호출 스택을 찾아 보면 해제 할 위치를 찾을 수 있습니다. 그것은 그것이 어떤 객체인지 알려줄 것입니다.

중단 점을 설정하는 가장 쉬운 방법은 다음과 같습니다.

  1. 실행으로 이동 ->보기 -> 중단 점 ( ALTCommandB)
  2. 목록 맨 아래로 스크롤하여 기호를 추가하십시오. malloc_error_break


답변

개체가 “이중 해제”된 경우 가장 일반적인 원인은 자동 해제 된 개체를 (불필요하게) 해제하고 포함하는 자동 해제 풀이 비워지면 나중에 자동 해제되는 것입니다.

추가 릴리스를 추적하는 가장 좋은 방법 은 Xcode에서 영향을받는 실행 파일에 대해 NSZombieEnabled 환경 변수 를 사용하는 것 입니다. 사용 방법에 대한 빠른 요약은 이 CocoaDev 위키 페이지를 확인 하십시오 . (이 페이지 외에도 Apple은 Xcode에서 코드를 디버깅하는 데 매우 모호하지만 유용한 팁을 문서화했으며, 그중 일부는 내 베이컨을 몇 번 이상 절약했습니다. developer.apple.com 에서이 기술 노트 를 확인하는 것이 좋습니다. — 링크 Cocoa의 Foundation 프레임 워크 섹션으로 이동합니다.)

편집 : 종종 Xcode 디버거 내에서 문제가되는 객체를 추적 할 수 있지만 Instruments를 사용하여 도움을 받으면 훨씬 더 쉽습니다. Xcode에서 Run → Start With Performance Tool → Object Allocations 를 선택하면 문제가되는 객체를 생성 된 위치까지 추적 할 수 있습니다. (위에서 설명한대로 좀비를 활성화 한 경우 가장 잘 작동합니다.) 참고 : Snow Leopard는 실행 메뉴에서도 액세스 할 수있는 도구에 좀비 도구를 추가합니다. $ 29만으로도 가치가있을 수 있습니다! 😉

여기에 관련된 SO 질문도 있습니다 .


답변

저는 Quinn Taylor의 답변에 더하여 저의 경험을 추가하고 싶습니다.

내 앱 중 하나에서 데이터를 구문 분석하고 핵심 데이터 개체에 저장하고 나중에 이러한 개체를 뷰에 표시해야합니다. 사실, 앱은 정상적으로 작동하고 전혀 충돌하지 않습니다. 여러 번 앞뒤로 탐색하는 스트레스 테스트를 시도하고 가능한 한 빨리 여러 뷰를 열려고 시도 할 때까지. 위의 메시지와 함께 앱이 충돌합니다.

나는 Quinn이 그의 대답에서 제안한 모든 방법을 시도했지만 정확한 원인이 어디인지 알아 내지 못했습니다.

NSZombieEnabled = YES를 설정하고 NSStackLogging = YES를 설정하고 명령 쉘 malloc_history를 실행하여 이유를 알아 냈지만 여전히 운이 없습니다. 항상 핵심 데이터 개체에 데이터를 저장하는 위치를 가리 킵니다. 사실 저는 거기에서 과도하게 릴리스 된 개체를 수천 번 확인했습니다. 이상한 것은 없습니다.

다양한 도구 (Allocations, Leaks 등 …)를 사용하여 Instruments에서 실행해도 여전히 도움이되지 않았습니다. Guard Malloc을 활성화하면 여전히 아무것도 얻지 못합니다.

최종 구조 : Core Data에서 개체를 가져온 뷰로 돌아가서 이러한 모든 개체에 유지 메시지를 보냈으며 이러한 변경 사항을 기록했습니다. 문제가 해결되었습니다 !!!

그래서 제가 하나를 유지하지 못했다는 것을 알게되었습니다. 그것이 바로 그 원인입니다. 내 경험을 공유하여 앱에 대한 또 다른 구조를 얻으십시오.


답변

Cmd + Shift + R을 눌러 디버거 콘솔을 엽니 다. 거기, 입력

break malloc_error_break

malloc_error_break함수 시작 부분에 중단 점을 설정 합니다.

주소 0x1068310에있는 개체를 찾으려면 디버거 콘솔에 다음을 입력 할 수 있습니다.

print-object 0x1068310

물론 개체가 아직 살아있는 동안이 작업을 수행해야합니다.이 작업을 수행 할 때 개체가 이미 해제 된 경우이 작업은 작동하지 않습니다.


답변

나를 위해 문제는

(gdb) call (void)_CFAutoreleasePoolPrintPools()

충돌 직후. 스택 맨 위에있는 주소가 범인의 주소였습니다. retain그리고 짜잔을 던져 .

로그 메시지에 제공된 주소는 나를 어디로도 가져 오지 못했습니다. 다양한 Instrumets에 나타나지 않았습니다. 이미 해제 된 내부 데이터에 대한 포인터입니다.


답변

Xcode 4에서 기호 중단 점 추가

Xcode 4와 관련된 업데이트입니다.

로부터 엑스 코드 4 사용 설명서 :

기호 중단 점을 추가하려면. . .

  1. 중단 점 탐색기의 왼쪽 하단에서 추가 버튼을 클릭합니다.
  2. Add Symbolic Breakpoint를 선택합니다.
  3. 기호 필드에 기호 이름을 입력하십시오.
  4. 완료를 클릭하십시오.


답변

이것이 Xcode의 Breakpoints 창에서 malloc_error_break 중단 점이 보이는 모습입니다. 작동하려면 확인란을 선택해야합니다.

대체 텍스트 http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png