2017-11-06 24 views
2

私はJavaプログラムからJNI経由で呼び出されるC++プログラムを持っており、C++プログラムのメモリアロケータをDoug Leaのdlmalloc実装に置き換えたいとしています(新しい演算子はmallocを下に呼び出すため、 。私はまた、C + +プログラムでstd:listとstd:mapを使用し、これらのライブラリ関数が "new"演算子の呼び出し時にdlmallocも使用することを望みます。私はLD_PRELOADを使用しようとしましたが、それはdmallocがJAVAプログラムからも呼び出され、私はそれを望んでいません。コンパイル中にC++プログラムをlibdlmalloc.soとリンクすると、すべてのC++ライブラリ関数がdlmallocを使用することが保証されますか?可能であれば、dlmallocとリンクする方法の例を提供できますか?おかげmalloc実装の置き換え

+0

* 'operator new'のライブラリバージョンが' std :: malloc'または 'std :: aligned_alloc'(C++ 17以降)を呼び出すかどうかは不明です* – Zereges

+0

これは興味深い質問です。'malloc'への呼び出しを' dlmalloc'(あるいはそれが呼び出されたもの)の呼び出しに置き換えるCマクロを設定したとしても、あなたのプログラムを再コンパイルするだけで十分ではないでしょうか。 'libc'は' malloc'を呼び出すことがあり、C++演算子newはおそらくは 'malloc'という名前の関数を呼び出して、プリプロセッサに介入する機会を与えません。 – Omnifarious

+0

私は 'dlmalloc'と呼ばれるグローバルな' operator new'と 'operator delete'を実装しておきます。 Cライブラリはまだいくつかの点でmallocを呼び出すかもしれませんが、Javaを受け入れる意思があれば、Cライブラリでもそれをやっても問題ありません。しかし、私は、C++はプログラムがグローバルな演算子newを独自のものでオーバーライドすることができること、そして標準ライブラリがこれを妨げないことを信じています。 – Omnifarious

答えて

1

あなたがプログラムを使用すると、(そのようrealpathなど)を解放する必要がメモリを割り当てる任意のlibc関数を呼び出していない場合、あなたはdlmallocに対する静的リンクして、慎重にエクスポートされたシンボルのセットを管理することができます。 JNIインターフェースによって実際に呼び出される関数(およびmallocfreeなどではない)だけをエクスポートすると、これは機能するはずです。

JNIのAPIはmalloc/free呼び出すコールバック関数を持っており、それらは元のプロセスからのもののままになりますが、malloc/free実装が一致するので、物事が一貫性を維持します。

しかし、あなたはあなたのdlmallocバリアントのみmmapbrk/sbrkは、オペレーティングシステムからの割り当てのために割り当ての古い形式はシステムmallocに干渉する可能性があるため使用していないことを確認してください。

ELF環境でのシンボル管理については、2.236(輸出管理)の​​が参考になります。

+0

これはWindows固有のソリューションですか?どのように慎重に輸出されたシンボルのセットを管理するのですか? – Omnifarious

+1

@Omnifarious、私は 'realpath'としてWindowsを考えていません。 ELFシンボル管理に関する文書への参照を追加しました。 –

+0

ありがとう。私はLinux(そして他のELFベースのUnix)上でこのようなことをすることは可能かもしれないと知っていましたが、決して試みたことはありません。 – Omnifarious

0

私は必ずしもリンカーでゲームをプレイすることは悪いとは思わないが、私は選択肢を持っている...

dlmallocは「malloc関数」でないシンボルとライブラリを持っている場合は、グローバルC++ operator newを上書きすることができますoperator new[]operator delete、およびoperator delete[]には、dlmallocバージョンのmallocを呼び出すものがあります。

これにより、ライブラリ関数を含むすべてのC++割り当てがオーバーロードされます。この動作は、標準によって保証されています。ただし、これらのオーバーロードの2つの異なるバージョンがある場合は、どちらが呼ばれているのかは不明です。しかし、標準ライブラリ自体にバージョンがある場合、バージョンが優先されるはずです。

これは、呼び出す可能性のあるC標準ライブラリ関数を対象としていません。彼らは依然としてmallocシンボルを使用しますが、リンカでゲームをプレイすることなくそれについて行うことはあまりありません。幸運なことに、ほとんどのC++プログラムでは、標準のCライブラリが割り当てを行う方法で呼び出される方法はたくさんありません。

プログラムの再コンパイルでは不十分です。実際には、newdelete演算子の標準C++実装は標準ライブラリ・ヘッダーには表示されないため、プリプロセッサーはmallocをdlmallocライブラリーが提供する関数に置き換える方法がありません。

関連する問題