2008-09-30 4 views
4

메모리 누수 문제를 디버그하려고합니다. mtrace()을 사용하여 malloc/free/realloc 추적을 얻습니다. 나는 내 prog을 돌 봤는데 지금은 거대한 로그 파일을 가지고있다. 여태까지는 그런대로 잘됐다. 하지만 파일을 해석하는 데 문제가 있습니다.GLIBC : 메모리 누수 디버깅 : mtrace()의 출력을 해석하는 방법

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502620 0x30 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1501460 0xa64 

이상한 점은 하나의 호출 (동일한 반송 주소)이 4 개의 할당을 담당한다는 것입니다.

심지어 낯선 사람 : 블록 0x2aaab43a1700가 해제되고 있지 않습니다 두 라인 사이

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa2c 
… 
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80 

.

누구든지 이것을 설명하는 방법을 알고 있습니까? 어떻게 하나의 결과를 4 개의 할당으로 부를 수 있습니까? 그리고 malloc은 이전에 이미 할당 된 주소를 어떻게 반환 할 수 있습니까?

편집 2008/09/30 : GLIBC (mtrace.pl)에서 제공하는 mtrace() 출력을 분석하는 스크립트는 여기에 도움이되지 않습니다. 그것은 단지 말할 것이다 : Alloc 0x2aaab43a1700 duplicate. 그러나 어떻게 이런 일이 일어날 수 있습니까?

답변

4

메모리를 할당하는 함수가 두 번 이상 호출되고 있습니다. 호출자 주소는 할당을 수행 한 코드를 가리키며 그 코드는 단순히 두 번 이상 실행됩니다. 여기

는 C의 예이다 :

void *allocate (void) 
{ 
    return (malloc(1000)); 
} 

int main() 
{ 
    mtrace(); 
    allocate(); 
    allocate(); 
} 

mtrace의 출력은 : 발신 주소가 동일한 방식

 
Memory not freed: 
----------------- 
      Address  Size  Caller 
0x0000000000601460 0x3e8 at 0x4004f6 
0x0000000000601850 0x3e8 at 0x4004f6 

주? 이것은 mtrace 분석 스크립트가 동일한 버그가 더 많이 보이기 때문에 동일한 메모리라고 말하는 이유입니다. 여러 메모리 누수가 발생합니다.

 
Memory not freed: 
----------------- 
      Address  Size  Caller 
0x0000000000601460 0x3e8 at /home/andrjohn/development/playground/test.c:6 
0x0000000000601850 0x3e8 at /home/andrjohn/development/playground/test.c:6 
0

하나의 가능한 설명은 동일한 기능이 다른 버퍼 크기를 할당한다는 것입니다. 그러한 예가 스트럿입니다.

두 번째 질문의 경우, 런타임이 프로세스가 종료 될 때까지 해제되지 않는 일부 "정적"스크래치 영역을 할당하는 것이 가능합니다. 그리고 그 시점에서, OS는 어쨌든 프로세스 후에 정리할 것입니다.

Java에서는 소멸자가 없으며 모든 객체에 대해 파이널 라이즈가 호출된다는 보장이 없습니다.

+0

그것은, 그것의 malloc/realloc을 /은 calloc 하나의 호출 이후 acually뿐만 아니라 하나의 함수 호출의 malloc()을 여러 번이다 : 당신이 할 수있는 경우 디버깅 플래그 (-g)로 컴파일

도움이됩니다 반송 주소는 동일합니다. 런타임에서 스크래치 영역을 할당하는 경우 두 번째 malloc()의 결과로 포인터가 반환되는 이유는 무엇입니까? –

0

valgrind에서 앱을 실행 해 봅니다. 실제로 유출되는 내용을 더 잘 볼 수 있습니다.

+0

내 경험은 : valgrind doesnt like java. 그것은 쉽게 충돌합니다. –

7

매우 혼란스럽고 반 직관적 인 mtrace의 직접 출력을 보았습니다. 다행히도,이 출력 결과를 파싱하는 데 매우 도움이되는 perl 스크립트 (glibc-utils에서 찾을 수있는 mtrace라고 함)가 있습니다.

는 같은 mtrace을에 디버깅 빌드를 컴파일하고 실행

$ gcc -g -o test test.c 
$ MALLOC_TRACE=mtrace.out ./test 
$ mtrace test mtrace.out 

Memory not freed: 
----------------- 
    Address  Size  Caller 
0x094d9378 0x400 at test.c:6 

출력은 많은을 소화하기 쉽게해야한다.

+0

이 스 크립트를 이미 확인했습니다. 그것은 내 스케치와 같은 출력을 줄 것입니다 : Alloc X가 중복되었습니다. –

+0

glibc-utils에 대해 알려주는 +1 –