malloc/free 호출 될 때마다 Stderr 로의 출력
문제
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와 같은 것을 사용해야합니다. 누수기 원하는대로 할 수 있습니다.
나는 이것을 직접 테스트하지 않았지만 이것이 효과가 있다고 확신합니다.
라이브러리를 다시 컴파일하고 싶지 않기 때문에 의미있는 출력 ( "23 바이트에 대한 새로운 호출")을 제공하려면 스택 트레이스를 가져와야 할 수 있습니다. 스택을 탐색하기 위해 함수를 사용한 것을 기억하지만 지금은 찾을 수 없습니다. 아마도 System () 및 PSTACK (1)에 대한 호출이 트릭을 수행 할 수 있습니다.
연산자를 다시 정의하고 삭제 하고이 새로운 정의를 STD C ++ 라이브러리보다 앞서 놓을 수 있습니다. 문제의 라이브러리가 사용중인 컨테이너 및 표준 구성 요소의 호출을 캡처하지 못할 수 있습니다. 이를 위해서는 리 링크가 필요합니다.
사용하면 LD_PRELOAD를 사용하여 운영자를 새롭게 변경하고 동적으로 삭제할 수 있습니다. 응용 프로그램이 동적으로 연결된 경우 리 링크가 필요하지 않습니다.
이 포인터가 도움이되기를 바랍니다. 레시피가 없어서 죄송합니다.