2014-08-29 7 views
1

기타 SO 답변에서 언급 한 것처럼 Linux에서 malloc (예 : here 참조) 호출을 가로 채기 위해 GNU ld의 래핑 메커니즘을 사용하고 있습니다. 사용 된 링커 플래그는 -Wl,--wrap=malloc이고 해당 void __wrap_malloc(size_t)도 정의됩니다. 모든 컴파일 장치가 동일한 바이너리로 링크 된 테스트 응용 프로그램에서 정상적으로 작동합니다.- wrap = malloc을 사용하여 컴파일 된 라이브러리를 동적으로로드하는 중 __real_malloc

지금은 dlopen()을 통해 주 프로그램에로드되는 동적으로 링크 된 라이브러리를 수정해야합니다. 라이브러리를 연결했지만 주 프로그램에로드하는 데 성공한 경우는 undefined symbol: __real_malloc으로 실패합니다.

라이브러리에서 nm을 실행하면 __wrap_malloc이 정의되어 있지만 __real_malloc은 정의되어 있지 않음을 보여줍니다. 그러나이 기술을 사용하는 경우 man ldthis 대답에 따라 malloc__wrap_malloc으로, __real_mallocmalloc을 가리켜 야합니다.

테스트 응용 프로그램에서 컴파일 된 개체 파일에서 __real_malloc은 정의되지 않았지만 실행 파일에 링크 된 후에 확인됩니다.

그렇다면 테스트 응용 프로그램에서는 심볼이 해석되지만 동적 라이브러리에서는 해석되지 않는 이유는 무엇입니까? 두 경우 모두이 기호를 해결해야하는 최종 링크 단계가 수행됩니다. __real_malloc을 해결하기 위해 동적 라이브러리의 링크 단계에서 다른 라이브러리를 추가해야합니까?

dlopen을 통해 동적 라이브러리를로드하는 대상 응용 프로그램을 수정할 수 없습니다.

답변

1

링크 된 질문의 코드 만 약간 변경하면됩니다.

testapp.c

#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 

typedef void f_t(void); 

int main() 
{ 
    void* h = dlopen("./malloc_wrapper.so", RTLD_NOW); 
    if (h == NULL) 
    { 
     puts(dlerror()); 
     exit(1); 
    } 

    f_t* f = (f_t*)dlsym(h, "test"); 

    if (f == NULL) 
    { 
     puts(dlerror()); 
     exit(1); 
    } 

    (*f)(); 

    return 0; 
} 

malloc_wrapper.c

#include <stdlib.h> /* added */ 
#include <stdio.h> 
void *__real_malloc (size_t); 

/* This function wraps the real malloc */ 
void *__wrap_malloc(size_t size) 
{ 
    void *lptr = __real_malloc(size); 
    printf("Malloc: %lu bytes @%p\n", size, lptr); 
    return lptr; 
} 

void test(void) /* added */ 
{ 
    free(malloc(1024)); 
} 

컴파일 및 실행됩니다. 컴파일 및 공유 객체 대신 실행 파일을 링크 할 때

gcc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so 
./testapp 
./malloc_wrapper.so: undefined symbol: __real_malloc 

은 아마 당신은 랩을 사용했다 :

gcc -Wl,-wrap,malloc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so 
gcc testapp.c -o testapp -ldl 
./testapp 
Malloc: 1024 bytes @0x1d44680 

같이 malloc_wrapper.so 컴파일 오류가 당신이 설명 재현?

+0

예를 들어 주셔서 감사 드리며 너무 늦게 늦어 져서 죄송합니다. 'extern "C"선언을 함수에 추가 한 후, 변경은'C++'와 동등한 것으로,'g ++ '로 파일을 컴파일하면이 예제에서 작동합니다. 불행하게도, 내가 작업하고있는 프로젝트는 훨씬 더 복잡합니다. 따라서 빌드 프로세스에서 문제가되는 것 같습니다. 문제에 대한 자세한 내용이 있으면 질문을 업데이트 해 드리겠습니다. – MKroehnert