Valgrind is a great tool for finding possible memory leaks in code written in C, C++, Java, Perl, Python, assembly code, Fortran, Ada, etc. I use it to check out if the provided code is ok, before I start porting it to GPU-code. It finds one of those devils in the details. But also for finding my own bugs when writing OpenCL-code, it has given me good feedback. Unfortunately it does not work well with optimised libraries, such as the OpenCL-driver from AMD.
You’ll get problems like below, which clutters the output.
==21436== Conditional jump or move depends on uninitialised value(s)
==21436== at 0x6993DF2: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x6C00F92: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x6BF76E5: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x6C048EA: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x6BED941: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x69550D3: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x69A6AA2: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x69A6AEE: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x69A9D07: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x68C5A53: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x68C8D41: ??? (in /usr/lib/fglrx/libamdocl64.so)
==21436== by 0x68C8FB5: ??? (in /usr/lib/fglrx/libamdocl64.so
How to fix this cluttering?
AMD has discussed the problem in their Knowledge Base and marks them as false alarms:
In the valgrind online documentation, it says:
“Using -O0 is also a good idea, if you can tolerate the slowdown. With -O1 line numbers in error messages can be inaccurate, although generally speaking Memchecking code compiled at -O1 works fairly well and is recommended. Use of -O2 and above is not recommended as Memcheck occasionally reports uninitialised-value errors which don’t really exist.”
Of course, the ACML libraries that we release are highly optimized for performance.
So it should be safe to ignore, assuming AMD tests their new drivers with Valgrind using -O0. (if not and you’re from AMD, then it’s a hint).
How to fix
Luckily you can tell Valgrind to ignore certain traces, using suppression files. Below is the one I generated for AMD’s library for ignore uninitialised conditional jumps and usage of uninitialised parameters in two functions I encountered. The “…” is a wild char for any “fun” or “obj”, but unfortunately doesn’t work for other options (at least to my knowledge). This means the filter is probably incomplete, so additions are welcome. If you want to learn to create suppression-rules, check out this page – you need to duplicate a Param-rule and change the function-name + param (the line with the brackets), and to give it a unique name.
{ libamdocl64_cond Memcheck:Cond ... obj:*/libamdocl64.so ... obj:*/libamdocl64.so } { libamdocl64_param_ioctl Memcheck:Param ioctl(generic) ... obj:*/libamdocl64.so } { libamdocl64_param_writebuf Memcheck:Param write(buf) ... obj:*/libamdocl64.so } { libamdocl64_cond_rindex Memcheck:Cond fun:rindex ... obj:*/libamdocl64.so } { libamdocl64_value8 Memcheck:Value8 obj:*/libamdocl64.so ... obj:*/libamdocl64.so } { libamdocl64_value8_rindex Memcheck:Value8 fun:rindex ... obj:*/libamdocl64.so } { libamdocl64_value8_strlen Memcheck:Value8 fun:strlen ... obj:*/libamdocl64.so } { libamdocl64_leak_possible Memcheck:Leak match-leak-kinds: possible fun:malloc obj:/usr/lib/fglrx/libamdocl64.so ... obj:/usr/lib/fglrx/libamdocl64.so } { libamdocl64_leak_definite Memcheck:Leak match-leak-kinds: definite fun:malloc obj:/usr/lib/fglrx/libamdocl64.so ... obj:/usr/lib/fglrx/libamdocl64.so } { libamdocl64_leak_definite_ati Memcheck:Leak match-leak-kinds: definite fun:malloc obj:/usr/lib/fglrx/libatiadlxx.so ... obj:/usr/lib/fglrx/libamdocl64.so } { libamdocl64_leak_reachable Memcheck:Leak match-leak-kinds: reachable fun:malloc obj:/usr/lib/fglrx/libamdocl64.so ... obj:/usr/lib/fglrx/libamdocl64.so } { libamdocl64_leak_reachable Memcheck:Leak match-leak-kinds: reachable fun:malloc ... obj:/usr/lib/fglrx/libamdocl64.so ... obj:/usr/lib/fglrx/libamdocl64.so }
(updated 2014/11/06 – Yikes! It also needs to suppress definite memory leaks)
This will remove the problems with calls to libamdocl64.so from the Valgrind-output. To use this suppression-file from the command-line, save the above as “libamdocl64.supp” and use:
valgrind --suppressions=/path/to/libamdocl64.supp --suppressions=/path/to/another.supp ./binary
Within Eclipse + Linux Tools, configure as below:
Or set it by default for each run in the file ~/.valgrindrc. Add one line with “–suppressions=/path/to/libamdocl64.supp”.
That should do it!
Valgrind is also available for OSX up to 10.7 and has limited support for 10.8. Check out this post to make Valgrind work for OSX 10.9.
Have any tips&tricks that other readers might find useful or have fixes for the supp-file? Feel free to add them to the comments.
Nice work! Honestly, I don’t think AMD has tested their system with Valgrind at -O0. Further, Valgrind rarely gives false alarms, regardless of -OX level. I think they should just fix it. However, your fix is really useful in the meanwhile 🙂 Thanks!
Good it helped you! I have put quite some time in giguring out how the “…” syntax to get the suppression-file working for any AMD-driver.
AMD is free to copy above info and give it as answer instead of saying “we don’t support it”.