2010-11-23 4 views
22

私はいくつかのglibデータ構造(GHashTable、GSListなど)を使用してライブラリを開発しています。私はvalgrindを使用してメモリリークを頻繁にチェックしています。 valgrindが指摘している問題のほとんどは修正するのが簡単ですが、理解できないものはいくつかあります。glibデータ型を使用するとValgrindがメモリを失う可能性があります

これらはすべて「おそらく失われた」と報告されています。 valgrindののスタックトレースの上部に

、私はいつも同じ4つのライブラリ見つける:

==29997== 1,512 bytes in 3 blocks are possibly lost in loss record 24 of 25 
==29997== at 0x4004B11: memalign (vg_replace_malloc.c:532) 
==29997== by 0x4004B6B: posix_memalign (vg_replace_malloc.c:660) 
==29997== by 0x5E9AC4: ??? (in /lib/libglib-2.0.so.0.1200.3) 
==29997== by 0x5EA4FE: g_slice_alloc (in /lib/libglib-2.0.so.0.1200.3) 

さらにダウンコールスタック内を、などg_key_file_newなどglibの関数の呼び出しは、()常にあります、 g_slist_prepend()、g_strsplit()、g_key_file_load_from_file()、g_file_get_contents()。

私の質問は以下のとおりです。

  • は、誰もがこの渡って来ると、それを回避する方法を発見しましたか?

  • これは私が無視できるものですか? hereが示唆しているように、メモリプールを使用しているglibによるのでしょうか?

私が使用しています

  • valgrindの-3.5.0
  • のglib-2.12.3
  • のgcc(GCC)4.1.2 20080704(Red Hatの4.1.2-48)
  • CentOSリリース5.5(最終)

答えて

32

のGLibはValgrindのを混乱させるいくつかの機能があります。

1つはメモリプールです(新しいglibではg_slice、古いものでは「mem chunks」)。これらは、リストノードなどの小さなオブジェクトに使用される特殊なアロケータです。 2番目の問題は、新しいメモリの初期化や解放されたスライス/チャンク内のデッドポインタの保持を避けることです。もちろん、だから、一緒に G_DEBUG=gc-friendly valgrind myprogram

:あなたがこの問題を解決することができ G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind myprogram

第三の問題は、GLibのは、単純に解放されていないが、永久的なプログラム状態とみなさんグローバル変数を持っているということです。たとえば、登録されたGTypeは決してアンロードされません。これは修正可能ではありませんが、valgrindはこれらのグローバル割り当てが失われたものではなく到達可能であることを示す必要があります。

+0

G_SLICE = always-mallocでプログラムを実行すると、すべての(可能な)メモリ損失がメモリプールのために発生するという私の疑惑を確認します。明確な答えのためにHavoc Pに感謝します。 – ttreitlinger

+0

GLib 2.32では、グローバル変数に関する記述がまだ真であることを確認できますか?ありがとう! –

+3

たとえば、gconvert.cの "static GHashTable * iconv_cache"など(ちょうど1つの例) –

0

glib-2.12はかなり古いです。

は、アプリケーションをコンパイルするためにそれを使用する(例えば--prefix =は/ usr/local/glibの-2.24で)、glibの-2.24になってみてコンパイルしてインストールしてください。

あなたはまだこれを持っている場合は、再度、glibのマニュアルを読むしよう:)

+0

残念ながら、私が開発しているソフトウェアがデフォルトのバージョンである2.12の管理対象サーバ上で実行されるので、このバージョンのglibが残っています – ttreitlinger

関連する問題