4

これは少し架空で大幅に簡略化されていますが...

サードパーティによって作成された関数を呼び出すプログラムを想定します。これらの当事者は敵対的ではないと見なすことができますが、「有能」であると見なすことはできません。各関数はいくつかの引数を取り、副作用があり、値を返します。実行されていない間は状態がありません。

目的は、すべてのmalloc(など)をログに記録し、関数の終了後にすべてを解放することで、メモリリークを引き起こさないようにすることです。

これは可能ですか?これは実用的ですか?

ps私にとって重要なのは、割り当てが持続しないようにすることです。そのため、それを行わずにメモリリークを削除する方法は、私には役立ちません。

4

11 に答える 11

5

オペレーティング システムまたは環境を指定しません。この回答では、Linux、glibc、および C を想定しています。

__malloc_hook、__free_hook、および __realloc_hook を、それぞれ malloc()、realloc()、および free() から呼び出される関数を指すように設定できます。プロトタイプを示す __malloc_hook マンページがあります。これらのフックにトラックの割り当てを追加してから、戻って glibc にメモリの割り当て/割り当て解除を処理させることができます。

サードパーティ関数が戻ったときに、ライブ割り当てを解放したいようです。-finstrument-functions を使用して、すべての関数の入り口と出口で gcc に呼び出しを自動的に挿入させる方法はありますが、それはあなたがやろうとしていることにはエレガントではないと思います。これらのサードパーティ関数のいずれかを呼び出した後、独自のコードでメモリ追跡ライブラリ内の関数を呼び出すことができますか? 次に、サードパーティ関数がまだ解放されていない割り当てがあるかどうかを確認できます。

于 2008-09-08T22:33:16.187 に答える
4

まず、とのエントリポイントを提供する必要がmalloc()ありfree()ます。#defineこのコードはすでにコンパイルされているので(右?) 、リダイレクトに頼ることはできません。

次に、これらを明白な方法で実装し、それらのルーチンをそれらのモジュールにリンクすることによって、それらが特定のモジュールからのものであることをログに記録できます。

最速の方法は、ロギングをまったく行わないことです。 使用するメモリの量が制限されている場合は、必要になるすべての「ヒープ」を事前に割り当てて、そこからアロケータを作成してみませんか?それが終わったら、「ヒープ」全体を解放すれば完了です。それよりも複雑な場合は、このアイデアを複数のヒープに拡張できます。

本当に「ログに記録」する必要があり、独自のアロケータを作成する必要がない場合は、ここにいくつかのアイデアがあります。1つは、ポインターと内部チェーンを備えたハッシュテーブルを使用することです。もう1つは、すべてのブロックの前に余分なスペースを割り当て、そこに、たとえばインデックスを含む独自の構造を「ログテーブル」に配置してから、ログテーブルエントリのフリーリストを保持することです(スタックとして、フリーリストを取得します)。または無料のものを戻すのはO(1))です。これはより多くのメモリを必要としますが、高速である必要があります。

実用的ですか?スピードヒットが許容できる限り、そうだと思います。

于 2008-09-08T22:24:51.243 に答える
3

別のプロセスでサードパーティの関数を実行し、ライブラリの使用が終了したらプロセスを閉じることができます。

于 2008-09-08T22:23:19.267 に答える
2

mallocをログに記録するよりも優れた解決策は、関数を呼び出すときに関数をサンドボックス化することです。つまり、メモリの固定セグメントへのアクセスを許可し、関数の実行が完了したらそのセグメントを解放します。

制限のない、無能なメモリ使用量は、悪意のあるコードと同じように損害を与える可能性があります。

于 2008-09-08T22:22:34.247 に答える
1

スタックにすべてのメモリを割り当てるように強制することはできませんか?このようにして、関数の終了後に解放されることが保証されます。

于 2008-09-08T22:21:43.937 に答える
1

過去に、割り当てと解放をログに記録し、各割り当てと解放を手動で照合する機能を含むメモリ管理サブシステムを備えたソフトウェア ライブラリを C で作成しました。これは、メモリ リークを見つけようとするときにある程度役に立ちましたが、使用するのが難しく、時間がかかりました。ログの数が圧倒的で、ログを理解するのに膨大な時間がかかりました。

そうは言っても、サードパーティのライブラリに大規模な割り当てがある場合、ログを介してこれを追跡することはおそらく非現実的です。Windows 環境で実行している場合は、Purify[1] や BoundsChecker[2] など、サードパーティ ライブラリのリークを検出できるツールを使用することをお勧めします。ツールへの投資は、節約された時間で元が取れるはずです。

[ 1]: http://www-01.ibm.com/software/awdtools/purify/

[2]: http://www.compuware.com/products/devpartner/visualc.htm BoundsChecker

于 2008-09-08T22:45:02.210 に答える
0

メモリリークが心配で、malloc / freeについて話しているので、Cにいると思います。また、質問に基づいて、サードパーティライブラリのソースコードにアクセスできないと思います。

私が考えることができる唯一のことは、呼び出しの前後にアプリのメモリ消費量を調べ、エラーメッセージが異なる場合はログに記録し、見つかったリークを修正するようにサードパーティベンダーを説得することです。

于 2008-09-08T22:26:24.487 に答える
0

お金に余裕がある場合は、Purify を使用して問題を追跡することを検討してください。それは驚異的に機能し、ソース コードや再コンパイルを必要としません。より安価な他のデバッグ用 malloc ライブラリも利用できます。Electric Fence は私が覚えている名前の 1 つです。とはいえ、Denton Gentry が言及したデバッグ フックも興味深いようです。

于 2008-10-21T03:00:09.223 に答える
0

Purify が苦手な方は、Valgrind をお試しください。6 年前よりもはるかに良くなり、Purify よりも飛び込みやすくなりました。

于 2008-10-21T03:40:38.563 に答える