In my last post, I covered Valgrind's high level overview. In this post, I will cover Valgrind's popular sub-tool: memcheck.
memcheck Overview
memcheck helps in detecting:
- Memory corruptions
- Writing/Reading to unallocated/freed memory, post heap blocks (overrun)
- Writing/Reading to unallocated stack
- buffer overrun: Passes overlapping source and destination memory blocks to memcpy() and related functions
- Incorrect Memory operations
- Reading uninitialized memory
- Double free
- Mismatched free (c++ relevant, not c)
- Passing inaccessible memory to system call
- Memory leaks
memcheck Usage
- Step1: Recompile the program enabling gdb & turning off compiler optimizations:
gcc -g prog.c -o <prog_name>
- Step2: Run the program in valgrind emulator:
valgrind --track-origins=yes <prog_name>
<prog_args>
------ Outputs memcheck's dynamic analysis information to console.
valgrind --log-file=<log_file> --track-origins=yes
<prog_name> <prog_args>
------ Stores memcheck's dynamic analysis information in log_file. memcheck's output is not easily readable, so I prefer storing the info in a log file for offline analysis.
I used the code at https://github.com/babuneelam/valgrind_tests/blob/master/vg_tests.c to explore 10 of the 11 tests:
- uninitialized use
- Read/Write after free
- buffer overrun
- Read/Write bad stack location (underrun)
- Memory Leak
- c++related test (ignore this)
- Overlapping memcpy
- double free
- pass unaddressable memory to system call
- Read/Write invalid stack location (overrun)
- Read/Write invalid global data location (overrun)
Here are the results:
root@babu-VirtualBox:~/valgrind_tests#
gcc -g vg_test.c -o vg_test.o
root@babu-VirtualBox:~/valgrind_tests#
root@babu-VirtualBox:~/valgrind_tests# valgrind --track-origins=yes --leak-check=full ./vg_test.o 1 2 3 4 5 7 8 9 10 11
.
.
.
root@babu-VirtualBox:~/valgrind_tests# valgrind
--log-file=vg_log --track-origins=yes --leak-check=full ./vg_test.o 1 2 3 4 5 7 8 9 10 11
10
*num = 0
i[-1] = 0
Please type a bunch of characters and hit enter.
34
root@babu-VirtualBox:~/valgrind_tests#
Valgrind expects the process to be terminated before reporting memory leak. I am yet to come up with a procedure that helps in collecting memory information without terminating the process.
Reporting and Analysis of memcheck results
I placed the above generated log file at https://github.com/babuneelam/valgrind_tests/blob/master/vg_log.
Memcheck's dynamic analysis results are output to console/log file as and when the running program encounters a run time memory error. As we can see in the above log, it also displays the entire stack trace of each memory error. Memcheck tracks addressability at the byte-level, and initialisation of values at the bit-level. As a result, it can detect the use of single uninitialised bits, and does not report spurious errors on bitfield operations.
Drawbacks
- Valgrind doesn't work well with linked libraries - static libraries seem to be working now, but dynamic libraries are still are not working. I am yet to come up with tests that show these deficiencies in memcheck.
- Performance impact of memcheck: The user space applications run 10-30x slower with memcheck. I am yet to come up with tests that measure the slowdown.
- The log file of memcheck is not intuitive. In my other post, I covered a GUI tool - Valkyrie - that addresses this issue.
- Requires recompilation of user space application for useful reporting. Valgrind works even on stock binaries. I tried memcheck without recompiling the sources. Here is the log: https://github.com/babuneelam/valgrind_tests/blob/master/vg_log_without_sources. The report is not that bad, but misses out line number information for the reported errors.
Reference:
http://valgrind.org/docs/manual/mc-manual.html
No comments:
Post a Comment