2010-02-23 4 views
3

나는 리눅스 악마를 썼는데, 지금은 꽤 잘 돌아 간다.하지만 메모리가 누출된다. (몇 시간 후에는 60 %의 시스템의 메모리). 이상한 것은 새로운/delete 연산자 만 사용하고 main 함수 주위에 try/catch 블럭이있어서 새로운 것으로 던져진 예외가 아니라는 것입니다 - 추측 된 메모리 부족으로 인해 어떤 시점에서 segfaults가 발생합니다 .이상한 메모리 누출을 디버그하는 방법 (C++)

나는 valgrind를 사용했지만 한 번만 작은 누출을 발견하고 아무것도 발견하지 못했습니다. 나는 gdb를 시도했지만, 앱이 -g -rdynamic 플래그로 컴파일 되었기 때문에 모든 주소를 함수 이름으로 변환하지 않는다.

메모리 누수 원인을 파악하는 데 사용할 수있는 몇 가지 메모리 디버깅 방법을 알려주시겠습니까?

+3

세그먼트 결함은 일반적으로 메모리가 부족하기 때문에 발생하지 않습니다. 메모리가 잘못된 방식으로 액세스되거나 (야생, 널 또는 삭제 된 포인터를 역 참조) 또는 관리가 잘못 되었기 때문에 발생합니다 (이중 삭제, 삭제 []/삭제 불일치 등). 프로그램이 나중에 실패 할 수 있도록 메모리를 손상시킬 수 있기 때문에 오류가 항상 발생하지는 않습니다. –

답변

4

Valgrind는 일반적으로 누출을 발견 할 때 매우 신뢰할 수 있으므로 메모리 누수가 확실합니까?

힙 프로파일 러를 사용하면 생성중인 개체와 예상 한 개체인지 확인할 수 있습니다. Massif은 유용한 도구 중 하나입니다.

3

C++ 용어의 "메모리 누출"은 해제되지 않았지만 더 이상 도달 할 수없는 고아 메모리를 나타냅니다. valgrind가 누수가 없다고 말한 경우 더 이상 필요하지 않은 객체에 대한 포인터를 유지하고있을 것입니다. 엄밀히 말하면 누수가 아니지만 결국 메모리 사용량이 급증합니다.

valgrind를 사용하려면 --show-reachable 플래그를 전달합니다.이 플래그는 앱 종료시 메모리에 계속 도달 할 수있는 모든 개체를 덤프합니다. 그런 다음 스택 추적을 조사하여 어떤 개체가 메모리에 너무 오래 보관되는지와 그 이유를 확인할 수 있습니다.

0

다른 사람들이 지적했듯이, 아마도 단순한 누출이 아닙니다. 잘못된 캐스트가 잘못되어 일부 객체의 유형을 잘못 해석 할 가능성이 큽니다. 또는 버퍼 오버/오버 플로우 또는 정수 롤오버 (2Gig를 넘는 일부 32 비트 부호있는 오프셋) 또는 매달려 포인터 ...

내 경험에 비추어 볼 때 복잡한 구조를 만들 때 구조의 공식 사양이 필요합니다. 특히 중요한 것은 불변의 집합입니다. 이를 통해 테스트 스위트와 런타임 검증자를 모두 구축하여 데이터가 여전히 일관되고 깔끔하다는 것을 확신 할 수 있습니다.

0

segfault가 발생할 때 어떤 일이 발생하는지 찾기위한 # 1 도구이기 때문에 먼저 gdb로 문제를 해결해보십시오. 그런 다음 충돌이 발생할 때까지 프로그램을 실행하고 시스템이 코어 파일을 생성하는지 확인하십시오 (코어 파일 작성을 허용하려면 ulimit -c unlimited을 사용하고, 데몬 인 경우주의하십시오. 실제로 데몬을 실행하는 사용자를 위해 수행해야합니다) . 이 시점에서 핵심 파일과 함께 gdb를 사용하여 segfault가 발생한 위치를 확인할 수 있습니다 (backtrack 명령 참조).

0

또한 스택 오버플로가 될 수 있습니다 (물론 이상하게 보일 수도 있지만 문제가 될 수 있습니다). 예를 들어 함수가 잠시 후 자신을 (암시 적으로 또는 명시 적으로) 호출하면이 문제가 발생할 수 있습니다. 나는 이것이 이상하고 매우 드문 문제라고 다시 말하지만, 모든 대답과 문제를 읽은 후에 그것이 내 마음에 온 것입니다.

0

Valgrind가 취약 할 수있는 한 가지는 스레드 응용 프로그램에서 누출을 찾는 것입니다. Valgrind가 모든 것을 직렬화하기 때문에 누출이 경쟁 조건의 결과라면 디버깅 중에 사라집니다.

특히 Java에서 디버깅 한 거의 모든 "누출"은 표준 컬렉션에서 무제한으로 증가한 결과입니다. 즉 정리되지 않는 벡터, 기대 이상으로 커지는 사전 등 Valgrind가 아무것도 찾지 못하면 실제 누수가 아닌 좋은 기회입니다.

+0

프로그램에 경쟁 조건이 없다면 문제가 될까요? 그렇지 않은 경우 OP가이 문제를 해결하기 시작해야합니다. – qdii

+0

문제는 아니지만 Valgrind의 성공적인 통과가 지표가 될 수 있습니다. 단일 스레딩 서버는 성능 외에도 부작용이 없어야합니다. – pestilence669

0

컴파일러 또는 링커에서 이상한 경고가 표시됩니다. libstdC++와 관련된 것이 있습니까? 우리는 libstdC++ (5와 6)의 두 개의 개별 버전에 대해 동시에 링크하는 문제가 있었고 이로 인해 우리에게 끔찍한 메모리 누수가 발생했습니다.

0

한 번 읽으면 예외가 발생하지 않고 메모리가 부족하면 new가 NULL을 반환합니다. 아마 그게 세그 폴트를 일으키는거야?

관련 문제