Memcheck x86 linux valgrind

The Valgrind Quick Start Guide

The Valgrind tool suite provides a number of debugging and profiling tools that help you make your programs faster and more correct. The most popular of these tools is called Memcheck. It can detect many memory-related errors that are common in C and C++ programs and that can lead to crashes and unpredictable behaviour. The rest of this guide gives the minimum information you need to start detecting memory errors in your program with Memcheck. For full documentation of Memcheck and the other tools, please read the User Manual.

2. Preparing your program

Compile your program with -g to include debugging information so that Memcheck’s error messages include exact line numbers. 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 running Memcheck on code compiled at -O1 works fairly well, and the speed improvement compared to running -O0 is quite significant. Use of -O2 and above is not recommended as Memcheck occasionally reports uninitialised-value errors which don’t really exist.

3. Running your program under Memcheck

valgrind --leak-check=yes myprog arg1 arg2

Memcheck is the default tool. The —leak-check option turns on the detailed memory leak detector. Your program will run much slower (eg. 20 to 30 times) than normal, and use a lot more memory. Memcheck will issue messages about memory errors and leaks that it detects.

4. Interpreting Memcheck’s output

#include void f(void) < int* x = malloc(10 * sizeof(int)); x[10] = 0; // problem 1: heap block overrun >// problem 2: memory leak — x not freed int main(void)

==19182== Invalid write of size 4 ==19182== at 0x804838F: f (example.c:6) ==19182== by 0x80483AB: main (example.c:11) ==19182== Address 0x1BA45050 is 0 bytes after a block of size 40 alloc'd ==19182== at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130) ==19182== by 0x8048385: f (example.c:5) ==19182== by 0x80483AB: main (example.c:11)
  • There is a lot of information in each error message; read it carefully.
  • The 19182 is the process ID; it’s usually unimportant.
  • The first line («Invalid write. «) tells you what kind of error it is. Here, the program wrote to some memory it should not have due to a heap block overrun.
  • Below the first line is a stack trace telling you where the problem occurred. Stack traces can get quite large, and be confusing, especially if you are using the C++ STL. Reading them from the bottom up can help. If the stack trace is not big enough, use the —num-callers option to make it bigger.
  • The code addresses (eg. 0x804838F) are usually unimportant, but occasionally crucial for tracking down weirder bugs.
  • Some error messages have a second component which describes the memory address involved. This one shows that the written memory is just past the end of a block allocated with malloc() on line 5 of example.c.
Читайте также:  Linux как сделать зип архив

It’s worth fixing errors in the order they are reported, as later errors can be caused by earlier errors. Failing to do this is a common cause of difficulty with Memcheck.

Memory leak messages look like this:

==19182== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==19182== at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130) ==19182== by 0x8048385: f (a.c:5) ==19182== by 0x80483AB: main (a.c:11)

The stack trace tells you where the leaked memory was allocated. Memcheck cannot tell you why the memory leaked, unfortunately. (Ignore the «vg_replace_malloc.c», that’s an implementation detail.)

There are several kinds of leaks; the two most important categories are:

  • «definitely lost»: your program is leaking memory — fix it!
  • «probably lost»: your program is leaking memory, unless you’re doing funny things with pointers (such as moving them to point to the middle of a heap block).

Memcheck also reports uses of uninitialised values, most commonly with the message «Conditional jump or move depends on uninitialised value(s)». It can be difficult to determine the root cause of these errors. Try using the —track-origins=yes to get extra information. This makes Memcheck run slower, but the extra information you get often saves a lot of time figuring out where the uninitialised values are coming from.

If you don’t understand an error message, please consult Explanation of error messages from Memcheck in the Valgrind User Manual which has examples of all the error messages Memcheck produces.

5. Caveats

Memcheck is not perfect; it occasionally produces false positives, and there are mechanisms for suppressing these (see Suppressing errors in the Valgrind User Manual). However, it is typically right 99% of the time, so you should be wary of ignoring its error messages. After all, you wouldn’t ignore warning messages produced by a compiler, right? The suppression mechanism is also useful if Memcheck is reporting errors in library code that you cannot change. The default suppression set hides a lot of these, but you may come across more.

Читайте также:  Brave для linux mint

Memcheck cannot detect every memory error your program has. For example, it can’t detect out-of-range reads or writes to arrays that are allocated statically or on the stack. But it should detect many errors that could crash your program (eg. cause a segmentation fault).

Try to make your program so clean that Memcheck reports no errors. Once you achieve this state, it is much easier to see when changes to the program cause Memcheck to report new errors. Experience from several years of Memcheck use shows that it is possible to make even huge programs run Memcheck-clean. For example, large parts of KDE, OpenOffice.org and Firefox are Memcheck-clean, or very close to it.

6. More information

Please consult the Valgrind FAQ and the Valgrind User Manual, which have much more information. Note that the other tools in the Valgrind distribution can be invoked with the —tool option.

Источник

Debugging C++ code with Valgrind on Linux

A brief intro about how to debug and optimize C++ development in linux using Valgrind.

Debugging C++ code with Valgrind on Linux

Finding memory bugs like memory-leaks, memory corruptions and memory access violations can be difficult if you don’t have the right tool to help you narrow down the scope and provide clues. This is what Valgrind does good for code written in C/C++, it can save you hours of frustration.

How to run

You can install valgrind using your package manager (for Ubuntu sudo apt install valgrind ). Your program can be complied with any compiler, but try to keep it on no optimizations to get most of valgrind)

For your program named hello , run

Understanding Valgrind

Valgrind is a debugging tool which is available on Linux, it’s an opensource project and is free to use. Valgrind helps with memory leak detection, threading bugs and can help optimize code using its profiling support. Valgrind is designed to work non-intrusively as possible with existing executable, this means you don’t need to re-link or re-build a binary in order to use Valgrind features. Simply run Valgrind passing it operational parameters and the executable to be tested along with any parameters the executable might accept.

Читайте также:  Rufus linux mint установка

The executable is run on a synthetic CPU provided by the Valgrind core, every single instruction executed is simulated, which will cause the executable to run much slower. Lets look at Valgrind by testing the Linux date command from the shell.

==20943== Memcheck, a memory error detector ==20943== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==20943== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==20943== Command: ./hello ==20943==  ================================================================================================== Hello World! ================================================================================================== ==20943==  ==20943== HEAP SUMMARY: ==20943==  in use at exit: 72,768 bytes in 3 blocks ==20943==  total heap usage: 6,247 allocs, 6,244 frees, 1,071,757 bytes allocated ==20943==  ==20943== 32 bytes in 1 blocks are still reachable in loss record 1 of 3 ==20943== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==20943== by 0x6340E77: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) ==20943== by 0x63F841E: sk_new (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) ==20943== by 0x60B94F9: .  (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) ==20943== by 0x60BB5F8: SSL_COMP_get_compression_methods (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) ==20943== by 0x60C0D82: SSL_library_init (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) ==20943== by 0x52BA77: boost::asio::ssl::detail::openssl_init_base::do_init::do_init() (openssl_init.ipp:39) ==20943== by 0x52BE42: boost::asio::ssl::detail::openssl_init_base::instance() (openssl_init.ipp:131) ==20943== by 0x52C955: boost::asio::ssl::detail::openssl_init::openssl_init() (openssl_init.hpp:60) ==20943== by 0x562DB2B: __static_initialization_and_destruction_0(int, int) (openssl_init.hpp:90) ==20943== by 0x562E538: _GLOBAL__sub_I_http_client.cpp (http_client.cpp:426) ==20943== by 0x40106C9: call_init.part.0 (dl-init.c:72) ==20943==  ==20943== 32 bytes in 1 blocks are still reachable in loss record 2 of 3 ==20943== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==20943== by 0x6340E77: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) ==20943== by 0x63F843C: sk_new (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0) ==20943== by 0x60B94F9: .  (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) ==20943== by 0x60BB5F8: SSL_COMP_get_compression_methods (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) ==20943== by 0x60C0D82: SSL_library_init (in /lib/x86_64-linux-gnu/libssl.so.1.0.0) ==20943== by 0x52BA77: boost::asio::ssl::detail::openssl_init_base::do_init::do_init() (openssl_init.ipp:39) ==20943== by 0x52BE42: boost::asio::ssl::detail::openssl_init_base::instance() (openssl_init.ipp:131) ==20943== by 0x52C955: boost::asio::ssl::detail::openssl_init::openssl_init() (openssl_init.hpp:60) ==20943== by 0x562DB2B: __static_initialization_and_destruction_0(int, int) (openssl_init.hpp:90) ==20943== by 0x562E538: _GLOBAL__sub_I_http_client.cpp (http_client.cpp:426) ==20943== by 0x40106C9: call_init.part.0 (dl-init.c:72) ==20943==  ==20943== 72,704 bytes in 1 blocks are still reachable in loss record 3 of 3 ==20943== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==20943== by 0x67ACEFF: .  (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21) ==20943== by 0x40106C9: call_init.part.0 (dl-init.c:72) ==20943== by 0x40107DA: call_init (dl-init.c:30) ==20943== by 0x40107DA: _dl_init (dl-init.c:120) ==20943== by 0x4000C69: .  (in /lib/x86_64-linux-gnu/ld-2.23.so) ==20943==  ==20943== LEAK SUMMARY: ==20943==  definitely lost: 0 bytes in 0 blocks ==20943==  indirectly lost: 0 bytes in 0 blocks ==20943==  possibly lost: 0 bytes in 0 blocks ==20943==  still reachable: 72,768 bytes in 3 blocks ==20943==  suppressed: 0 bytes in 0 blocks ==20943==  ==20943== For counts of detected and suppressed errors, rerun with: -v ==20943== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Источник

Оцените статью
Adblock
detector