5

私はvalgrindを使用してメモリリークを追跡しようとしています.mysqlから配布されたmysql c ++クライアントです。

例 (resultset.cpp) と私自身のプログラムの両方で、解放されていない単一の 56 バイト ブロックがあります。私自身のプログラムでは、mysql クライアントへの呼び出しにリークがあったことを突き止めました。

テストを実行したときの結果は次のとおりです。

valgrind --leak-check=full --show-reachable=yes ./my-executable

==29858== Memcheck, a memory error detector
==29858== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==29858== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==29858== Command: ./my-executable
==29858==
==29858==
==29858== HEAP SUMMARY:
==29858==     in use at exit: 56 bytes in 1 blocks
==29858==   total heap usage: 693 allocs, 692 frees, 308,667 bytes allocated
==29858==
==29858== 56 bytes in 1 blocks are still reachable in loss record 1 of 1
==29858==    at 0x4C284A8: malloc (vg_replace_malloc.c:236)
==29858==    by 0x400D334: _dl_map_object_deps (dl-deps.c:506)
==29858==    by 0x4013652: dl_open_worker (dl-open.c:291)
==29858==    by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==29858==    by 0x4012FF9: _dl_open (dl-open.c:583)
==29858==    by 0x7077BCF: do_dlopen (dl-libc.c:86)
==29858==    by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==29858==    by 0x7077D26: __libc_dlopen_mode (dl-libc.c:47)
==29858==    by 0x72E5FEB: pthread_cancel_init (unwind-forcedunwind.c:53)
==29858==    by 0x72E614B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==29858==    by 0x72E408F: __pthread_unwind (unwind.c:130)
==29858==    by 0x72DDEB4: pthread_exit (pthreadP.h:265)
==29858==
==29858== LEAK SUMMARY:
==29858==    definitely lost: 0 bytes in 0 blocks
==29858==    indirectly lost: 0 bytes in 0 blocks
==29858==      possibly lost: 0 bytes in 0 blocks
==29858==    still reachable: 56 bytes in 1 blocks
==29858==         suppressed: 0 bytes in 0 blocks
==29858==
==29858== For counts of detected and suppressed errors, rerun with: -v
==29858== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 6)

これに関していくつか質問があります。

  1. --show-reachable ブロックをどのように解釈すればよいですか?
  2. そのブロックは、私が試してエラーをゼロにするのに役立ちますか?
  3. ブロックが役に立たない場合、valgrind にはリークを追跡するのに役立つ別のメカニズムがありますか?
  4. そうでない場合、これを絞り込むのに役立つ他のツール (できれば Linux の OSS) はありますか?

前もって感謝します..

更新:これは、pthread_exit の定義のためにシステムで見つけたコードです。これが呼び出されている実際のソースであるかどうかはわかりません。しかし、もしそうなら、誰が何がうまくいかないのか説明できますか?

void
pthread_exit (void *retval)
{
    /*  specific to PTHREAD_TO_WINTHREAD  */

    ExitThread ((DWORD) ((size_t) retval));  /*  thread becomes signalled so its death can be waited upon  */
    /*NOTREACHED*/
    assert (0); return;  /*  void fnc; can't return an error code  */
}
4

1 に答える 1

6

到達可能とは、プログラムが終了したときにブロックが有効なポインターをスコープ内で参照していたことを意味します。これは、プログラムが終了時にすべてを明示的に解放しないことを示します。これは、基盤となる OS に依存しているためです。探す必要があるのは、失われたブロックです。メモリのブロックは、それらへのすべての参照を失い、もはや解放できません。

したがって、56 バイトはおそらく main に割り当てられ、明示的に解放されませんでした。あなたが投稿したものは、メモリリークを示していません。これは、main が割り当てられたもの以外のすべてを解放する main を示しています。これは、main が終了すると、すべてのメモリがカーネルによって再利用されると想定しているためです。

具体的には、この仮定を行っているのは pthread (主に) です (これは、過去 15 年以上に書かれた製品で見つかったほぼすべての有効な仮定です)。終了時にまだ有効な参照を持っているブロックを解放する必要があることは少し論争の的になりますが、この特定の質問について言及する必要があるのは、仮定が行われたということだけです。

編集

実際には、終了時に何かをクリーンアップするわけではありませんが、説明したように、その時点に到達するpthread_exit()と、おそらくクリーンアップする必要はありません (またはできない可能性があります)。

于 2012-08-07T17:00:58.987 に答える