2011-12-18 8 views
1

私はLD_PRELOADを使用してPyDict_New関数をインターセプトしようとしています。私はthis recipeがpythonインタプリタのgetpidで動作することを確認しましたが、代わりにadapted it to use PyDict_Newがありますが、期待通りに機能しません。私は辞書を明確に割り当てていますが、この関数を使用する必要がありますが、オーバーライドは呼び出されていません。はPyDict_NewをLD_PRELOADで傍受することはできません

私は間違っていますか?


背景:私は非常に大きなシステムで問題をデバッグしようとしています。私は、不正な参照カウントを持つdictがあることを発見しました。私はdictが最初に割り当てられた場所とどこに問題が現れているのかを知っていますが、いくつかの中間時間ではカウントが悪くなることは確かです。単純なコードトレースはキャッシュされ再利用されません(PyDict_Newを介して)gcシステムによって実行されます。

答えて

3

LD_PRELOADは、動的にロードされる関数のみをオーバーロードできます。 Pythonバイナリを使用している場合、PyDict_Newは動的にロードされないため、ダイナミックローダがそのシンボルの解像度を横取りする方法はありません。独自のバイナリをコンパイルしてlibpython.soとリンクすることで独自の "python"を作成すると、うまくいくはずです。ここでは、あなたのプログラム(/tmp/foo.c)に置く必要があると思いますものです:

#include "Python.h" 

int 
main(int argc, char **argv) 
{ 
    return Py_Main(argc, argv); 
} 

そして、あなたは、単純にそれを構築することができます のgcc -o fooの-Iは/ usr /含ん/ python2.7 foo.c -lpython2.7

これを実行すると、LD_PRELOAD on ./fooが機能するはずです。

+0

「自分自身を動的に読み込む」とはどういう意味ですか? LD_PRELOADは、-Bsymbolicでコンパイルされていない共有ライブラリのグローバル関数を無効にすることはできませんか? –

+1

私は、実行可能ファイルのシンボルがld.soによって動的にロードされないという事実を指摘していました。それらはld.soによってロードされないので、LD_PRELOADは単に使用されません。この場合、OPがオーバーライドしたい機能はpython実行可能ファイルにコンパイルされ、共有ライブラリからld.soによってロードされませんでした。提供されたソリューションでは、すべてのPythonがlibpython2.7.soから動的にロードされるため、LD_PRELOADが機能します。 -Bsymbolicに関しては、ライブラリの実行可能ファイルを最初に見るのではなく、独自のシンボルを優先させることが唯一の効果であると私は理解しています。 –

+0

私はこれを試してみる必要があります。 – bukzor

1

Pythonのソースディストリビューション(あなたに関連するバージョン用)をダウンロードし、デバッグモードでビルドして、アプリケーションを実行する方がはるかに簡単だと思います。

この方法では、問題をデバッグする際の柔軟性が大幅に向上します。たとえば、条件付きブレークポイントをPyDict_Newに設定することも、独自のバージョンに置き換えることもできます。

+0

これは質問には対処しませんが、私はそれを投票します。私はそれを考えなかった。私はそのような低レベルで働くことに慣れていないと思う。 – bukzor

+0

@bukzor:あなたの質問は、直接アドレス指定されるための十分な詳細を提供していません(コード、コンパイル/リンケージ/実行パス、期待する出力、表示される出力などを表示します) )。それにもかかわらず、私が提案するアプローチはあなたの問題をより速くデバッグする必要がありますIMHO –

+0

私のポストのリンクをクリックすると、その情報がすべて見つかります。たぶん私はそれらをもっと顕著にする/明らかにする必要があります。明日はやるよ。 – bukzor

関連する問題