2017-11-17 7 views
2

에은 calloc 원인 재귀 :최우선의 malloc, 무료 내가 아래에 리눅스 플랫폼의 기능 <code>malloc</code>, <code>calloc</code> 및 <code>free</code> 기능을 대체 한 리눅스

#include <stdio.h> 
#include <dlfcn.h> 
#include <stdlib.h> 
typedef void* (*MALLOCFN)(size_t); 
typedef void* (*CALLOCFN)(size_t, size_t); 
typedef void* (*CALLOCFN)(size_t, size_t); 
typedef void (*FREEFN)(void *); 
MALLOCFN real_malloc = (MALLOCFN) 0; 
CALLOCFN real_calloc = (CALLOCFN) 0; 
FREEFN real_free = (FREEFN) 0; 
void *get_realfn(const char *fnm) 
{ 
    void *pfunc = (void *) NULL; 
    printf("searching for original %s\n", fnm); 
    pfunc = dlsym(RTLD_NEXT, fnm); 
    if (pfunc) printf("found original %s\n", fnm); 
    else printf("not found original %s\n", fnm); 
    return pfunc; 
} 
void *malloc(size_t s) 
{ 
    printf("called malloc\n"); 
    if(real_malloc == NULL) real_malloc = (MALLOCFN) get_realfn("malloc"); 
    if (real_malloc) return real_malloc(s); 
    else return NULL; 
} 
void *calloc(size_t s1, size_t s2) 
{ 
    printf("called calloc\n"); 
    if(real_calloc == NULL) real_calloc = (CALLOCFN) get_realfn("calloc"); 
    if (real_calloc) return real_calloc(s1, s2); 
    else return NULL; 
} 
void free (void * ptr) 
{ 
    printf("called free\n"); 
    if(real_free == NULL) real_free = (FREEFN) get_realfn("free"); 
    if (real_free) real_free(ptr); 
} 
int main() 
{ 
    char * c1 = (char *) malloc(400); 
    char * c2 = (char *) malloc(400); 
    free(c2); free(c1); 
    return 0; 
} 

C 프로그램 (testalloc.c)의 g를 사용하여 구축됩니다 ++ 4.9 컴파일러의 버전 0.2 :

: 도시 출력

g++ -g testalloc.c -ldl -o testalloc; 

처음 몇 줄은 무한 재귀와 충돌에 입사, 아래와 같다 0

called malloc 
searching for original malloc 
called free 
searching for original free 
called free 
searching for original free 
called free 
searching for original free 
called free 
searching for original free 
called free 
. . . . 

재귀를 피하는 방법을 제안하십시오.

+0

gcc, 랩 옵션. – someuser

답변

3

printf 함수는 메모리를 할당 할 수 있습니다. 따라서 printf 전에 호출하면 "실제"함수 포인터가 할당되지 않고 삽입 된 함수가 무한 재귀를 발생시킵니다. 따라서 끼워 넣기 기능에 printf 문을 사용하지 마십시오.

실제로 인쇄해야하는 경우 stdio 라이브러리 기능을 우회하는 syscall(2)을 사용하십시오.

#include <sys/syscall.h> 

... 

syscall(SYS_write, STDOUT_FILENO, "searching for original\n", 
            sizeof "searching for original\n" - 1); 
+0

왜'syscall (SYS_write ...) '에 신경 써야하니? 그냥'write()'를 사용하십시오. 아마도 –

+1

. 내가 생각하는 습관. – usr

+0

그게 더 낫겠 어, dlsym은 malloc이나 calloc을 호출 할 수 있니? 내 디버거는 malloc에서 dlsym을 호출 한 다음 calloc이 무한 재귀를 일으키는 것을 보여줍니다. dlsym에서 overrided malloc/calloc을 호출하는 것을 피할 수 있습니까? –