2012-09-27 4 views
9

릴리스 바이너리에로드 될 공유 라이브러리에서 메모리 누수를 찾는 방법을 알아야합니다. 공유 라이브러리 -g 옵션을 사용하여 빌드 한 공유 라이브러리를 의미하지만 공유 라이브러리를로드하는 바이너리는 -g 옵션으로 빌드되지 않습니다.valgrind - 공유 라이브러리에서 메모리 누수 찾기

다음과 같이 누출 신고를 받았습니다.

==739== at 0x4A05809: malloc (vg_replace_malloc.c:149) 
==739== by 0x84781B1: ??? 
==739== by 0x87507F5: ??? 
==739== by 0x874CF47: ??? 
==739== by 0x874E657: ??? 
==739== by 0x874F7C2: ??? 
==739== by 0x8779C0C: ??? 

공유 라이브러리에서 누출의 스택 추적을 얻는 방법을 알려주십시오.

답변

6

실제로 누출이 공유 라이브러리에서 발생한다고 가정하면 문제는 주 실행 파일에서 디버깅이 부족하다고 생각하지 않습니다.

더 많은 문제는 실행 파일이 완료되기 전에 dlclose을 호출하여 공유 라이브러리를 언로드한다는 것입니다. 즉, valgrind가 누출 여부를 확인할 때 라이브러리가 더 이상로드되지 않아 라이브러리에 대한 모든 심볼 정보가 사라졌습니다.

실행 파일을 다시 빌드 할 수있는 가장 쉬운 방법은 일시적으로 라이브러리를 중지하여 dlclose을 호출하여 라이브러리가 끝까지로드되도록 유지하는 것입니다. 당신이 할 수없는 경우

, 다음과 같이로드 라이브러리를 유지하기 위해 LD_PRELOAD를 사용해보십시오 :

LD_PRELOAD="/path/to/library.so" valgrind my-executable 

희망조차가 닫힌 후로드 라이브러리를 유지로 동적 링커를 속일 것이다 .

+0

dlclose 이후에 심볼을 언로드하는 옵션을 제공하는 패치가있었습니다. 패치가 작동하고 여러 번 사용했습니다. 그러나 패치는 이전 버전이었고 지금은 썩은 것 같습니다. https://bugs.kde.org/show_bug.cgi?id=79362 – k0n3ru

+0

@TomH : "생략 dlclose"해결 방법은 많은 위양성을 유발할 수 있다고 지적하겠습니다. 스택에 힙에 있던 요소를 파괴하는 객체가있는 경우, dlclose가 먼저 파괴를 수행 했으므로 출력에 누출로 표시됩니다. – newhouse

+0

그리고 valgrind가 64 비트이지만 32 번째 디버그를하면 두 번째 것도 제대로 작동하지 않습니다. – newhouse

2

앞의 대답에서 알 수 있듯이 프로그램을 종료하기 전에 라이브러리를 닫았 기 때문에 기호 정보를 사용할 수 없기 때문입니다.

LD_PRELOAD를 사용하면 나에게 적합하지 않습니다. 이제 두 가지 구조가 생겼습니다. 명시 적으로 dlclose()를 호출하지 않는 함수. 이 빌드에서 valgrind는 동적 연결에서 예상하는 것처럼 행 번호 정보를 올바르게보고합니다.