문제

Linux/GCC/C ++를 사용하면 Malloc/Free/New/Delete가 호출 될 때마다 Stderr에 무언가를 녹음하고 싶습니다. 라이브러리의 메모리 할당을 이해하려고 노력하고 있으므로 단위 테스트를 실행하는 동안이 출력을 생성하고 싶습니다. MEM 누출 감지에 Valgrind를 사용하지만 로그 할당만으로 옵션을 찾을 수 없습니다.

어떤 아이디어? 가능한 가장 간단한 솔루션을 찾고 있습니다. 라이브러리를 다시 컴파일하는 것은 옵션이 아닙니다.

도움이 되었습니까?

해결책

malloc_hook(3) 전 세계적으로 자신의 개입을 할 수 있습니다 malloc 기능. (거기 있습니다 __realloc_hook __free_hook 또한, 나는 단순성을 위해 방금 그들을 남겼습니다.)

#include <stdio.h>
#include <malloc.h>

static void *(*old_malloc_hook)(size_t, const void *);

static void *new_malloc_hook(size_t size, const void *caller) {
    void *mem;

    __malloc_hook = old_malloc_hook;
    mem = malloc(size);
    fprintf(stderr, "%p: malloc(%zu) = %p\n", caller, size, mem);
    __malloc_hook = new_malloc_hook;

    return mem;
}

static void init_my_hooks(void) {
    old_malloc_hook = __malloc_hook;
    __malloc_hook = new_malloc_hook;
}

void (*__malloc_initialize_hook)(void) = init_my_hooks;
$ cat >mem.c <<'EOF'
(위의 코드)
EOF
$ cc -fPIC -shared -o mem.so mem.c
$ LD_PRELOAD=./mem.so ls
0x7ffc14931adc: malloc(5) = 0xb40010
0x7ffc1492c6b0: malloc(120) = 0xb40030
0x7ffc1497f61a: malloc(12) = 0xb40010
0x7ffc1492be38: malloc(776) = 0xb400b0
…

printf 전화 할 수 있습니다 malloc, 그래서 우리는 후크를 일시적으로 취소하는 이유입니다. 당신이 연결할 때 이것에주의하십시오 malloc 어떠한 방식으로.

다른 팁

ltrace를 사용하여 Malloc/Free로 전화를 걸 수 있습니다.

#include <stdlib.h>

int main (void)
{
  void *ptr = malloc(10);
  free(ptr);

  return 0;
}


$ g++ test.cpp -o test
$ ltrace -e malloc,free ./test
malloc(10)                                       = 0x804a008
free(0x804a008)                                  = <void>
+++ exited (status 0) +++

다시 컴파일하지 않고 새/삭제 호출을 추적하려면 LD_PRELOAD와 같은 것을 사용해야합니다. 누수기 원하는대로 할 수 있습니다.

이 기사 (하단으로 스크롤) 글로벌을 무시하는 방법에 대한 매우 명확하고 간결한 설명을 제공합니다. new 그리고 delete C ++의 연산자 ( new[], 그러나 개념이 비슷합니다).

Linux에서 작업하고 GCC로 작업하기 때문에 Malloc 및 무료로 우선적 인 경우 가장 쉬운 방법은 사용하는 것입니다. malloc_hook 그리고 free_hook. 여기 이러한 기능이 어떻게 작동하는지에 대한 아주 좋은 설명입니다.

나는 이것을 직접 테스트하지 않았지만 이것이 효과가 있다고 확신합니다.

  • 라이브러리를 다시 컴파일하고 싶지 않기 때문에 의미있는 출력 ( "23 바이트에 대한 새로운 호출")을 제공하려면 스택 트레이스를 가져와야 할 수 있습니다. 스택을 탐색하기 위해 함수를 사용한 것을 기억하지만 지금은 찾을 수 없습니다. 아마도 System () 및 PSTACK (1)에 대한 호출이 트릭을 수행 할 수 있습니다.

  • 연산자를 다시 정의하고 삭제 하고이 새로운 정의를 STD C ++ 라이브러리보다 앞서 놓을 수 있습니다. 문제의 라이브러리가 사용중인 컨테이너 및 표준 구성 요소의 호출을 캡처하지 못할 수 있습니다. 이를 위해서는 리 링크가 필요합니다.

  • 사용하면 LD_PRELOAD를 사용하여 운영자를 새롭게 변경하고 동적으로 삭제할 수 있습니다. 응용 프로그램이 동적으로 연결된 경우 리 링크가 필요하지 않습니다.

이 포인터가 도움이되기를 바랍니다. 레시피가 없어서 죄송합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top