Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to locate a free/delete mismatch reported by Valgrind in a multithreaded program?

Here is the Valgring report:

==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

How can I know which thread is it as the thread number varies from one execution to another ? Will assigning names to my threads help here ?

EDIT: I don't think it will as this is mentioned in the DRD section of the manual.

I'm using valgrind-3.1.1 on Red Hat enterprise Linux AS4.

like image 597
philant Avatar asked Oct 06 '10 12:10

philant


3 Answers

You are likely freeing a global variable (the address: 0x4DC4EE0 is very close to where globals live by default on Linux/x86_64).

Run the program under GDB, then do info symbol 0x4DC4EE0, and GDB should tell you all you need to know.

Update:
Valgrind 3.6 actually reports the global symbol already. For example, given this buggy program:

#include <stdlib.h>

int x;

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

Valgrind 3.6 reports:

==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"
like image 123
Employed Russian Avatar answered Nov 06 '22 12:11

Employed Russian


I finally found the explanation for this: my unit-test executable was linked to a [third party] library it didn't use. I re-linked it without that library and the problem went away.

Also the error was detected in __libc_freeres(), a function of the gnu libc that free resources at the end of the execution. The problem might lie in the library or in the glibc.
The following Valgrind Linux-specific option can be used to avoid this error: --run-libc-freeres=no. Notice this can make the leak detection less efficient.

like image 30
philant Avatar answered Nov 06 '22 13:11

philant


You can use the macro DRD_GET_DRD_THREADID to display the thread IDs when the thread starts. You can also give a name in the print to help. See the DRD Manual

EDIT Maybe I'm not specific here.. but I think you'll need to link in some valgrind libs when you build a debug version of your code (maybe with a compile option or something). You can use the DRD_GET_DRD_THREADID from within the thread and get a name you assigned when it starts - then you can write that info to a file or to the console. There's no way to tell DRD to print the name I don't think, so you have to use a combo.

like image 1
NG. Avatar answered Nov 06 '22 12:11

NG.