web-dev-qa-db-ja.com

Linuxでの軽量メモリリークデバッグ

私は最初に既存の回答を探しましたが、ValgrindがLinuxでのメモリリークデバッグのためのみんなのお気に入りのツールであることがわかりました。残念ながらValgrindは私の目的では機能しないようです。その理由を説明しようと思います。

制約:

  • リークはお客様の環境でのみ再現されます。特定の法的制限により、既存のバイナリを使用する必要があります。再構築なし。
  • 通常の環境では、アプリケーションはCPUを最大10%消費します。たとえば、CPU使用率の最大10倍の増加を許容できるとします。 Valgrindデフォルトmemcheck設定を使用すると、アプリケーションの応答性が大幅に低下します期間。

私が必要とするものは、Microsoftの同等物です[〜#〜] umdh [〜#〜]:各ヒープ割り当てのスタックトレースをオンにしてから、スタックごとにグループ化され、割り当てカウントの降順で並べられたすべての割り当てをダンプします。私たちのアプリはWindowsとLinuxの両方のプラットフォームで出荷されるので、[〜#〜] umdh [〜#〜]でのWindowsのパフォーマンスはまだ許容範囲です。

ここに私が検討したツール/方法があります

  • Valgrind 's-memcheckおよび–massifツールこれらは必要以上に多くの処理を実行し(すべての割り当てポインターのプロセスメモリ全体をスキャンするなど)、速度が遅すぎて、まだ私が正確に実行していません
    必要(カウントでソートされたコールスタックをダンプする)なので、出力を解析するスクリプトをいくつか記述する必要があります
  • dmallocライブラリ(dmalloc.com)には新しいバイナリが必要です
  • LeakTracer( http://www.andreasen.org/LeakTracer/ )はC++でのみ機能しますnew/delete(私は必要ですmalloc/freeも)、スタックごとのグループ化とソート機能はありません
  • LD_PRELOADメカニズムを使用して自分自身を.soライブラリとしてツールを実装する( LD_PRELOADメカニズムを使用して 'malloc'をオーバーライドする )Linux用のコーディングスキルを考えると、少なくとも1週間はかかり、自転車を発明しているような気がします。 。

私は何かを逃しましたか?軽量Valgrindオプションまたは既存のLD_PRELOADツールはありますか?

17
glagolig

驚いたことに、私はオープンソースドメインでMicrosoftのUMDHのようなものを見つけることができなかったか、すぐにダウンロードできませんでした。 (私は Google Heap Leak Checker も調べましたが、UMDHではなくValgrindに似ています)。そのため、参照ポイントとして malloc instrumentation プロジェクトを使用して、自分でツールを作成しました。

https://github.com/glagolig/heapwatch

このツールにはいくつかの制限がありますが、私の目的には問題なく機能しました。

1
glagolig

GNU libcにはmallocデバッグが組み込まれています。

http://www.gnu.org/software/libc/manual/html_node/Allocation-Debugging.html

LD_PRELOADを使用して、独自の.soからmtrace()を呼び出します。

#include <mcheck.h>
static void prepare(void) __attribute__((constructor));
static void prepare(void)
{
    mtrace();
}

それをコンパイルします:

gcc -shared -fPIC dbg.c -o dbg.so

それを実行します:

export MALLOC_TRACE=out.txt
LD_PRELOAD=./dbg.so ./my-leaky-program

後で出力ファイルを検査します。

mtrace ./my-leaky-program out.txt

そして、あなたは次のようなものを得るでしょう:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000001bda460     0x96  at /tmp/test/src/test.c:7

もちろん、スタック全体をダンプする独自のmallocフックを自由に作成してください(役立つと思われる場合は backtrace() を呼び出します)。

行番号や関数名は、バイナリのデバッグ情報をどこかに保持した場合に取得できます(たとえば、バイナリにデバッグ情報が組み込まれている場合、またはobjcopy --only-keep-debug my-leaky-program my-leaky-program.debug)。


また、BoehmのGCを試すこともできます。これはリークディテクターとしても機能します。

http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html

15
DanielKO

私が発表したばかりのheaptrackユーティリティを宣伝したいと思います。詳細については、こちらをご覧ください: http://milianw.de/blog/heaptrack-a-heap-memory-profiler-for-linux

ヒープウォッチツールと比較すると、libunwindと後でlibbacktraceを使用して、DWARFデバッグ情報によるバックトレースの注釈を遅らせるため、パフォーマンスははるかに優れているはずです。

もっとフィードバックが欲しいので、試してみてください!

4
milianw

memleax でうまくいくはずです。

プログラムを再コンパイルしたり、ターゲットプロセスを再起動したりせずに、実行中のプロセスのメモリリークをアタッチしてデバッグします。それは非常に便利で、生産環境に適しています。

Malloc/free()呼び出しに対してのみトラップするため、Vagrildよりもパフォーマンスへの影響が少ないはずです。

GNU/Linux-x86_64およびFreeBSD-AMD64で動作します。

注:私は著者です。どんな提案でも歓迎します

3
Bingzheng Wu

MemoryScapeがニーズを満たします。これは、TotalViewデバッガに付属する動的メモリデバッグツールです。

http://www.roguewave.com/products/memoryscape.aspx

2
SebGR

@glagolig、

はい、MemoryScapeはスタックの場所によって割り当てをグループ化できます。

評価版は入手できましたか?ボットのように見えないメールアドレスを使用したと仮定すると、かなり迅速に私たちから返信されるべきでした。そうでない場合、または技術的な問題が発生している場合は、私に一言またはテクニカルサポートチームに連絡してください。

クリス・ゴットブラス

Rogue Wave SoftwareのTotalViewのプリンシパルプロダクトマネージャー

メール:名。姓(で)roguewave。 com

1
Chris Gottbrath

Chapと呼ばれる無料のオープンソースツールがあり、必要な機能のほとんどを実行できます。具体的にはスタックトレースを提供しませんが、まったく計測を必要としないため、非常に軽量なツールです。必要なのは、プロセスがすでにバグを示していると確信した時点で、問題のプロセスのライブコアを取得できることです(そのため、プロセスがリークしている、または大きすぎるなどと考えています)。

詳細については、 https://github.com/vmware/chap を参照してください

0
Tim Boddy

また、Googleのgperftoolsの使用を検討することもできます。これには、LD_PRELOADを介してロードできるヒーププロファイラーがあります。また、tcmallocおよびリークチェッカーをバイナリにリンクし、必要な場合にのみ有効にすることもできます。

詳細については、 https://github.com/gperftools/gperftools を参照してください

0
Gerald Chu