2016-06-23 3 views
3

私はすべてのアリーナですべてのmalloc_chunkを反復しようとしています。すべてのmallocチャンクを反復する方法(glibc)

top_chunkはそれの内部top_chunk、に基づくものアリーナの内側上部チャンクをポイントし、そこのIは、各アリーナを知っているようにしている(メモリリークやメモリ破損調査のために、コア・ファイルに基づいて、デバッグ)コードに基づいprev_sizeサイズ、(glibcの/のmalloc/malloc.c): enter image description here Iは、以前の連続チャンクを取得し、その後、ループ1つのアリーナ内のすべてのチャンクができます。 (私はWinDBG:!heap -stat -hのようなサイズと数のチャンクを統計できます)また、prev_sizeサイズに基づいて、チャンクが壊れているかどうかを確認できます。

アリーナ(malloc_state)には、次のアリーナを指すの次のというメンバー変数があります。それから私はすべてのアリーナのチャンクをループすることができます。

しかし、チャンクが割り当てられていない場合、prev_sizeが無効で、以前のmalloc_chunkを取得する方法が問題になりましたか?または、この方法は正しくありません。


質問の背景:

私たちが持っているメモリリークのバグが(私たちのプロジェクトは、分散ストレージクラスタです)いくつかのオンラインデータノードで報告されたメモリリークです。

  1. 我々はテストクラスタ内のバグを再現するためにvalrgindを使用しますが、残念ながら私たちは何を取得:私たちがしたし、その結果どのような

  2. 私はヒープの詳細を調べようとしましたが、ヒープチャンクを分析し、WinDBG(これはメモリリークとメモリ破損を助長する非常に面白いヒープコマンドを持っていました)私が尋ねた質問によってブロックされました。

  3. 私はvalgrind-massifを使って割り当てを分析しています(これは非常に詳細で興味深いと思いますが、どの割り当てにどのくらいのメモリが必要かを示すことができます)。 Massifはいくつかの手がかりを示し、私たちはこれに従ってコードをチェックし、最終的に漏れを見つけました(マップは非常に巨大で、適切な使い方ですが、ホルダークラスのデストラクタで消去します。

glicのmalloc構造の詳細については、gdbヒープのソースコードについて詳しく調べていきます。

+0

これは、GDBの質問やWinDbgの質問のいずれかであるが、それは、両方することはできません私見。私unserstandingから私はWinDbgのタグを削除することをお勧めしたい(「コアダンプ」と「アリーナ」私にはWinDbgの用語のように見えるしていません) –

+0

はい、それはGDBの問題ではなく、WinDbgの質問 –

+1

あなたが 'に興味があるかもしれないですgdb-heap'プロジェクトは、gdbで動作し、glibc mallocアリーナを解剖する方法を知っているPythonコードを含みます。 –

答えて

1

はまず、mallocの実装の詳細を掘り下げる前に、あなたの時間は、より良いvalgrindなどのツールと一緒に過ごしたことがあり、あるいは内部ヒープの一貫性があなたのために仕事をチェックできるようにMALLOC_CHECK_環境変数で実行されます。あなたが尋ねたので、

しかし、....

のglibcのmalloc.cは、以前のチャンクを見ているに関するいくつかの有用なコメントがあります。

いくつかの特に興味深いものは以下のとおりです。

/* Note that we cannot even look at prev unless it is not inuse */

そして:

If prev_inuse is set for any given chunk, then you CANNOT determine the size of the previous chunk, and might even get a memory addressing fault when trying to do so.

これはただのmalloc implimentationの制限です。以前のチャンクが使用されているときは、サイズを格納するフッターが割り当てのユーザーデータによって代わりに使用されます。

それはあなたのケースを助けることはありませんが、あなたは前のチャンクがprev_inuseマクロが何をするか、以下で使用されているかどうかを確認することができます。

#define PREV_INUSE 0x1 
#define prev_inuse(p) ((p)->size & PREV_INUSE) 

現在のチャンクのサイズの下位ビットをチェックします。 (すべてのチャンクサイズは4で割り切れるので、下位2ビットはステータスに使用できます)。これは、あなたの反復を止めてから、無人の土地に行くのを助けます。

残念ながら、あなたはまだ、すべてのチャンクを訪れる前に、早期にあなたのループを終了することと思います。

あなたが本当に上のすべてのチャンクを反復処理したい場合、私はあなたがmalloc_state::topで開始することをお勧めしますとtopnext_chunknext_chunkまでのポイントをたどるだろう。

+0

Thxをショーンは、私はあなたが本当に、私はあなたがmalloc_state ::トップでスタートし、トップにnext_chunkポイントまでnext_chunkに従うことをお勧めしたいすべてのチャンクを反復処理したい場合、私は」、あなたが言及した方法を理解していません。 "、tmalloc_state :: topは最初のチャンクではなく、物理的に最後のチャンクです。残念ながら、バグを再現するためにvalgrindを使用しようとしましたが、リークは報告されませんでした。バグは私たちの1つのデータノードで報告され、数日後にメモリが制限に達する。それを再現するには時間が必要です。 –

関連する問題