malloc "double free"오류의 원인을 찾는 방법은 무엇입니까?


80

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

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

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

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

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


3
더 많은 사람들을 확보하기 위해이 게시물을 iPhone으로 태그 할 수도 있습니다.
Benny Wong

4
보다 적절한 다른 태그를 위해 "iphone"태그를 제거했습니다.
Quinn Taylor

3
이 iPhone 질문에 iPhone 태그가 누락 된 이유를 상상할 수 없습니다. "autorelease"와 같은 다른 태그보다 "iPhone"을 팔로우하는 사람이 더 많을 것입니다. "autorelease"를 찾으려면 검색하고 태그를 따르지 않습니다. . 난에 "아이폰"다시 넣어 그래서
Nosredna

6
"iphone"태그를 제거한 이유는 질문에 대한 내용이 iPhone에만 해당되지 않기 때문입니다. 유일한 링크는 iPhone 앱에서 발생하지만 C 또는 Objective-C 응용 프로그램에서 똑같은 오류가 발생할 수 있다는 것입니다. 나는 iPhone을 팔로우하는 사람들이 아무렇지도 않게 여기에 관심이있을 것이라고 기대하지 않습니다. 오히려 "double free"또는 "malloc_error_break"와 같은 것을 검색하는 사람들이 될 것이고, 그들이 "iPhone"을 던지면 여전히 나타날 것입니다. . 태그에 대해 다투지 말고 대답하는 사람들이 질문이 가장 적합한 위치를 알 수 있다는 점을 고려하십시오.
Quinn Taylor

3
이 질문은 적어도 Cocoa에 한정됩니다. iPhone 태그가 불쾌하다면 코코아 태그는 어떻습니까? 명백한 의도는 XCode의 Cocoa에서 Objective-C에 적용됩니다. Windows, Linux 또는 XCode 컨텍스트 외부에서 Objective-C가 아닙니다.
runako

답변:


38

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

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

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

1
나는 그것을 시도했지만 나는 얻는다 : malloc_error_break를 dissamble 할 수 없습니다 .... 무슨 뜻입니까?
gonso

3
autorelease double free에 대한 도움말이 없습니다. 그는 좀비를 필요로
로저

58
@gonso — 궁금한 점이 있습니다.이 방법이 효과가 없다면 왜 답으로 받아들였습니까?
Quinn Taylor

8
엑스 코드 4.3.2에서 중단 점에서 찾을 수 있습니다 보기 → 항법 → 쇼 중단 점 네비게이터 또는 ⌘6 (Cmd를-6)
안드레아스 지맥

46

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

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

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

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


1
대답에 연결된 CocoaDev 위키 페이지가 죽었습니다 :(
Devarshi


12

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

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

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

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

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

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

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


9

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

break malloc_error_break

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

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

print-object 0x1068310

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


이것은 자동 릴리스이며 그는 좀비가 필요합니다.
Rog

1
마지막으로 내가 한 일은 AutoreleasePoll 외부에서 "의심스러운"메서드를 호출하는 것이 었습니다. 웃긴 생각은 여전히 ​​경고를 받았지만 중단 점은 없었습니다. 줄을 찾을 때까지 블록을 주석 처리했습니다. stringWithFormat (할당 또는 복사 없음)으로 만든 문자열을 자동 해제했습니다. 팁에 감사드립니다! Gonso
gonso

이 특정 유형의 버그의 경우 malloc_error_break를 중단해도 문제를 찾는 데 도움이되지 않았습니다. 항상 좀비를 활성화해야했습니다.
Quinn Taylor

XCode 4에서 malloc_error_break에 대한 중단 점 설정에 대한 지침은 여기를 참조하십시오. stackoverflow.com/questions/6969407/…
benvolioT

1
@Zammbi : po별칭을 사용 하거나 expr -o. 이 답변이 처음 작성된 이후 몇 년 동안 Xcode에서 사용하는 디버깅 엔진은 GDB에서 LLDB로 변경되었으며 LLDB에는 다른 명령 집합이 있습니다.
Adam Rosenfield 2015 년

4

나를 위해 문제는

(gdb) call (void)_CFAutoreleasePoolPrintPools()

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

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


4

Xcode 4에서 기호 중단 점 추가

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

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

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

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


2

클래스를 확인하고 dealloc 메소드를 살펴보십시오. 당신이 전화를 신경 쓰십시오[super dealloc].

나는 똑같은 문제가 있었고 [self dealloc]대신 전화하고 있음을 알았습니다 . 주의를 기울이지 않는 것뿐입니다.


2

사용 가능한 개체를 찾고 응용 프로그램을 중단하는 방법은 아래 단계를 참조하십시오.

1) " Breakpoint navigator "를 클릭하십시오 .
2) 그런 다음 아래 에있는 " + "버튼을 클릭합니다.
3) 목록에서 " Symbolic Breakpoint ... "를 추가합니다 .
4) " Symbol "옵션 에 " malloc_error_break "키워드를 추가합니다 .

또는 아래의 GIF 프레젠테이션을 참조 할 수도 있습니다.

GIF 표현


1

이것은 일반적으로 safari 또는 safari 미리보기와 같은 일부 관리자에 의해 발생합니다. 게시물 또는 게시물질문을 참조하십시오 .

AutoMatically Show Web ....의 선택을 제거하면이 문제가 제거됩니다.

사파리 또는 사파리 미리보기를 닫아도이 문제가 제거되지는 않습니다. 그리고 사파리와 사파리 미리보기를 모두 선택 해제해야합니다.

그래도 해결되지 않으면이 답변을 참조 하거나 게시 하여 디버그하십시오.

Safari 미리보기에서 자동 검사 선택 해제


0

Xcode에서 줄 번호의 왼쪽을 클릭하여 중단 점을 설정합니다. 그런 다음 "빌드 및 디버그"를 수행하여 시작할 수 있습니다.

autorelease메모리는 아이폰의 필수품이기 때문에 당신이 만든 물건을 가지지 않는 것이 좋습니다 . Apple은 명시 적으로 release.


0

일반적으로 이러한 종류의 메모리 및 포인터 문제를 찾으려면 Valgrind 와 같은 런타임 메모리 오류 검사기에 대해 코드를 실행하려고합니다 . 이것은 당신의 코드가 크래시를 유발하는 것 외에도 잘못하고있는 많은 것들을 지적 할 수 있어야합니다.

Valgrind 는 OSX에서 작동 할 수 있습니다 ( "지원되지 않고 불완전하고 버그가 있음"이라고 말하지만). 누군가 약간의 해킹으로 iPhone SDK 실행 파일 에서 작동하도록했습니다 .

XCode의 일부인 Instruments를 사용해 볼 수 있습니다. 여기에서 실행하기위한 튜토리얼이 있습니다 .


1
악기는 갈 길이다. 개체 할당 도구를 사용하고 좀비를 켭니다. (또는 그냥 좀비 템플릿을 사용하세요). Valgrind는 최후의 수단입니다. 매우 느리고 종종 단순히 작동하지 않습니다.
bbum 2009-06-30

0

만약이 malloc_error_break도움이되지 않는다 ...

이 오류를 해결하는 가장 좋은 방법은 기기NSZombies켠 상태에서 실행 하는 것입니다. Zombie가 메시지를 받으면 Instruments에서 플래그를 지정하고 코드 라인을 직접 추적 할 수 있습니다.

Snow Leopard가 필요했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.