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.
Related Posts
Improving FinanceBench for GPUs Part II – low hanging fruit
We found a finance benchmark for GPUs and wanted to show we could speed its algorithms up. Like a lot! Following the initial work done in porting ...
The Art of Benchmarking
How fast is your software? The simpler the software setup, the easier to answer this question. The more complex the software, the more the answer will ...
Birthday present! Free 1-day Online GPGPU crash course: CUDA / HIP / OpenCL
Stream HPC is 10 years old on 1 April 2020. Therefore we offer our one day GPGPU crash course for free that whole month. Now Corona (and fear for i ...
Problem solving tactic: making black boxes smaller
We are a problem solving company first, specialised in HPC - building software close to the processor. The more projects we finish, the more it's clea ...