2016-12-25 3 views
2

私はメモリトラッカーとリークディテクタがどのように動作するのか理解したいので、私はこの考え方を持っています。実行可能ファイルを持っています。通常のシステム関数( "malloc "、" realloc "...)。実行可能ファイルにユーザー定義の 'malloc'を使用させることは可能ですか?

私自身の機能は、そのようなことについてはthik、(静的または共有)、または単にオブジェクトファイル(「の.o」)ライブラリに格納されています。

void *my_own_malloc(unsigned long size) { 
    printf("allocate: %lu\n", size); 
    return malloc(size); 
} 

PS:私はする必要はありません(私はソースコードを持っていない)

PS2を実行可能なソースコードを変更します。私はすべての異なるプラットフォームで(Windowsの、OSはX & Linuxの...)

+0

注入された機能は、「malloc関数」として、いくつかの名前を持たなければならないということですが、注入された関数の内部システム「malloc関数」への呼び出しがあります。これは、次のコードを生成しますおそらく無限の再帰関数を生成するでしょうか? –

答えて

3

私が知らないことをやりたいです他のプラットフォームではありますが、GNU/Linuxでは小さなメモリトラッキングライブラリをあらかじめロードすることができますy LD_PRELOAD自分のmallocfreeが定義されている環境変数。

自分自身のmallocは実際の関数を使用してメモリを割り当てたいと思うかもしれないので、ここで再帰的な問題が発生する可能性があります。これを回避するために、dlsym関数は、RTLD_NEXT引数を使用して、次の(つまり、実際の)malloc関数へのポインタを取得できます。この

非常に小さなテストには、以下のようになります。私たちは、このファイルfakemalloc.cを呼び出す場合

#define _GNU_SOURCE 
#include <dlfcn.h> 
#include <stdio.h> 

void *malloc(size_t size) 
{ 
    static void *(*real_malloc)(size_t size) = 0; 

    if (!real_malloc) 
     real_malloc = dlsym(RTLD_NEXT, "malloc"); 

    void *result = real_malloc(size); 
    fprintf(stderr, "malloc(%d) = %p\n", (int)size, result); 
    return result; 
} 

void free(void *ptr) 
{ 
    static void (*real_free)(void *ptr) = 0; 
    if (!real_free) 
     real_free = dlsym(RTLD_NEXT, "free"); 

    real_free(ptr); 
    fprintf(stderr, "free(%p)\n", ptr); 
} 

、それは

gcc -fPIC -shared -Wl,-soname,fakemalloc.so -o fakemalloc.so fakemalloc.c -ldl 

としてコマンドでfakemalloc.so共有オブジェクトにコンパイルすることができますテストは、lsコマンドの呼び出しで発生したmallocfree通話見て、あなたが実行する必要があると思い

LD_PRELOAD=/path/to/fakemalloc.so ls 

EDIT:コメントで述べたように、glibcの-システムでは、あなたは機能__libc_malloc__libc_freeを使用してRTLD_NEXTアプローチを回避することができます。ここで問題@Lolrapa

#include <stdio.h> 

void *__libc_malloc(size_t size); 
void *__libc_free(void *ptr); 

void *malloc(size_t size) 
{ 
    void *result = __libc_malloc(size); 
    fprintf(stderr, "malloc(%d) = %p\n", (int)size, result); 
    return result; 
} 

void free(void *ptr) 
{ 
    __libc_free(ptr); 
    fprintf(stderr, "free(%p)\n", ptr); 
} 
+0

ありがとうございました! 'LD_PRELOAD'はすべて必要なものなので、ビルドの手順も便利です。 'DYLD_INSERT_LIBRARIES'あなたはまた、(' RTLD_NEXT'トリックを必要としない)交換用のmallocルーチンで '__libc_malloc'を呼び出すことにより、システムのmallocを呼び出すことができ、glibcのベースのシステムでOS Xの –

+2

で同等のかもしれ –

+0

多分印刷メッセージはfree()を呼び出すなどして、未定義の可能性があるビヘイビアをbevoreし、改行によってまだ見つからない場合(stderrが実際のファイルである場合)、結果をフラッシュします。 – 12431234123412341234123

関連する問題