4

でプログラムを実行することにより、実行時mallocに呼び出しをインターセプトするライブラリを作成しています。freeLD_PRELOAD=mylib myexe

と への呼び出しはインターセプトで問題mallocありません。free私の問題は、 mylib に別の関数があり、 が使用されているときにインターセプトしたいのですが、およびLD_PRELOADの呼び出しのように「機能しない」理由がわかりません。mallocfree

mylib.c で:

void* malloc(size_t s)
{
    return doMyMalloc();
}

void free(void* p)
{
    doMyFree(p);
}

void otherThing(size_t)
{
    doThing();
}

myexe.cpp で:

#include <malloc.h>

extern "C" void otherThing(size_t);  // Compile with -Wl,--unresolved-symbols=ignore-all

int main(int argc, char* argv[])
{
    void* x = malloc(1000);   // Successfully intercepted.
    free(x);  // Successfully intercepted.
    otherThing(1);  // Segfault.
}

私がそれを機能させることができた1つの方法は、次のことです。

typedef void (*FUNC)(size_t);
FUNC otherThing = NULL;

int main(int argc, char* argv[])
{
    otherThing = (FUNC)dlsym(RTLD_NEXT, "otherThing");
    otherThing(1);  // Successfully calls mylib's otherThing().
}

しかし、私はこのすべてのコードを書きたくありません。mallocと のためにそれをする必要はありませんfreeLD_PRELOAD接頭辞がなくてもプログラムがクラッシュしても問題ありません。

4

2 に答える 2

0

LD_PRELOAD2 つの異なる問題を解決するために 1つのソリューション ( ) を適用しているように感じます。まず、パッチmalloc()を適用しfree()ます。あなたはそれを機能させました-素晴らしいです。次に、ビルド時にどのライブラリにもリンクせず、実行時にのみリンクするランタイム「プラグイン」システムが必要です。これは通常、 と を使用して行われdlopen()ますdlsym()。これらを使用することをお勧めします。

アイデアは、ビルド時に の特定の実装を指定したくないということですがotherThing()、実行時に何らかの実装が必要です (そうしないと、当然のことながらクラッシュすることが予想されます)。したがって、それについて明示し、実行時に関数名を解決するために使用しましょうdlsym()。もちろん、見つからない場合のエラー検出も行います。

を定義する場所についてはotherThing()、 に指定された完全に別のファイルdlopen()、または に指定できますmylib(この場合、ファイル名として NULL を に渡しますdlopen())。

于 2013-04-21T06:03:26.007 に答える