如何在多线程程序中找到Valgrind报告的空闲/删除不匹配?

时间:2010-10-06 12:16:34

标签: c++ multithreading valgrind

以下是Valgring报告:

==14546== Thread 5:
==14546== Invalid free() / delete / delete[]
==14546==    at 0x490555D: free (vg_replace_malloc.c:235)
==14546==    by 0x3BF7EFAA8F: free_mem (in /lib64/tls/libc-2.3.4.so)
==14546==    by 0x3BF7EFA581: __libc_freeres (in /lib64/tls/libc-2.3.4.so)
==14546==    by 0x4802676: _vgw_freeres (vg_preloaded.c:62)
==14546==  Address 0x4DC4EE0 is not stack'd, malloc'd or (recently) free'd

我怎么知道它是哪个线程,因为线程编号因执行而异? assigning names to my threads会在这里提供帮助吗?

编辑:我认为不会这样,因为手册的DRD部分提到了这一点。

我在Red Hat企业Linux AS4上使用valgrind-3.1.1。

3 个答案:

答案 0 :(得分:6)

您可能正在释放一个全局变量(地址:0x4DC4EE0非常接近于Linux / x86_64上默认情况下global所在的位置。)

在GDB下运行程序,然后执行info symbol 0x4DC4EE0,GDB应该告诉您需要知道的所有内容。

更新:
Valgrind 3.6实际上已经报告了全局符号。例如,鉴于这个错误的程序:

#include <stdlib.h>

int x;

int main()
{
  free(&x);
  return 0;
}

Valgrind 3.6报告:

==18731== Invalid free() / delete / delete[]
==18731==    at 0x4C240E8: free /tmp/vg/coregrind/m_replacemalloc/vg_replace_malloc.c:394
==18731==    by 0x4004AA: main /home/t.c:7
==18731==  Address 0x60089c is 0 bytes inside data symbol "x"

答案 1 :(得分:2)

我终于找到了解释:我的单元测试可执行文件链接到它没有使用的[第三方]库。我没有那个库重新链接它,问题就消失了。

此外,在__libc_freeres()中检测到错误,这是gnu libc的一个功能,它在执行结束时释放资源。问题可能出在图书馆或者glibc中 以下Valgrind Linux-specific option可用于避免此错误:--run-libc-freeres=no。请注意,这可能会使泄漏检测效率降低。

答案 2 :(得分:1)

您可以使用宏DRD_GET_DRD_THREADID在线程启动时显示线程ID。您还可以在打印中给出一个名称以提供帮助。请参阅DRD Manual

编辑也许我在这里并不具体......但我认为你需要在构建代码的调试版本时链接到一些valgrind库(可能带有编译选项或其他东西) )。您可以在线程中使用DRD_GET_DRD_THREADID并获取启动时指定的名称 - 然后您可以将该信息写入文件或控制台。没有办法告诉DRD打印我不认为的名字,所以你必须使用一个组合。