Sign in Join
Wiki copytemporary

Debugging with Valgrind: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Introduction
22
33Valgrind is system for debugging and profiling Linux programs. It comprises of the Valgrind framework and set of tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can read about Valgrind here <https://valgrind.org/>
44
55A program running under Valgrind is not executed directly by the CPU. Instead it runs on a synthetic CPU provided by Valgrind. This allows Valgrind to have full control and track program and resources very meticulously.
66
77Valgrind can be used as standalone issue reporting or performance profiling tool. Also it can be used as a debugger. For this it includes VGDB utility that is GDB-compatible interface to Valgrind.
88
99The debugging applications stack is following:
1010
1111- GDB
1212- VGDB
1313- Valgrind executing YourProgram
1414
1515Though GDB can connect to VGDB directly (via interprocess communication), Lazarus cannot use this mode. You have to use Remote debugging over TCP. In this setup VGDB plays role of GDBServer listening on a TCP port, and Lazarus via GDB connects to it.
1616
1717So the debugging applications stack with Lazarus will be:
1818
1919- Lazarus IDE
2020- GDB
2121- tcp/ip
2222- VGDB
2323- Valgrind executing YourProgram
2424
2525Usually you will run all parts on same computer. But there is possibility to run them on 2 computers via network.
2626
2727In the following example everything will be on same computer. Network interface will be localhost and TCP port will be 33333.
2828
2929## Configuration
3030
3131### Install valgrind in your system
3232
3333Refer to Valgrind resources to install it.
3434
3535### Compile your program
3636
3737(here it is named valgrind_test1.pas) with Valgrind option (-gv). Select menu Project -\> Project Options
3838
39-<figure>
4039<img src="valgrind_project_options.png" title="valgrind_project_options.png" width="600" />
41-<figcaption>valgrind_project_options.png</figcaption>
42-</figure>
4340
4441### Configure Lazarus debugger.
4542
4643Select menu Tools -\> Options
4744
48-<figure>
4945<img src="valgrind_tools_options.png" title="valgrind_tools_options.png" width="600" />
50-<figcaption>valgrind_tools_options.png</figcaption>
51-</figure>
5246
5347## Debugging
5448
5549### Start Valgrind and VGDB in a separate shell
5650
5751```shell
5852valgrind --tool=memcheck --leak-check=yes --log-file=valgrind.trc --vgdb-error=0 ./valgrind_test1 &
5953sleep 2; vgdb --port=33333
6054```
6155
6256### Run your program in Lazarus and debug it
6357
6458Actually the program is already run by Valgrind, it is just staying in debugger and waiting for continue.
6559
6660Please note Valgrind is accurate but it is not a fastest debugger. Execution will be much slower than usual. Be patient.
6761
6862Lazarus via VGDB communicates with the program in Valgrind. You can set breakpoints, inspect variable values and so on, like in regular debugger.
6963
7064Lasarus will stop on lines where Valgrind throws exceptions. Valgrind tracks memory usage very carefully and detects the issues where FPC, RTL and a Memory Manager may ignore memory misuse. Like in example below, at line 4.
7165
7266``` pascal
7367 mo:=TMyObj.Create;
7468 mo.Field:=12345;
7569 mo.Free;
7670 if mo.Field = 0 // Mistakenly accessing released memory block
7771 then exit;
7872```
7973
8074Lazarus will show a message when Valgrind issues an exception.
8175
82-<figure>
8376<img src="valgrind_error.png" title="valgrind_error.png" width="400" />
84-<figcaption>valgrind_error.png</figcaption>
85-</figure>
8677
8778After you close it Lazasarus will position you on a source row where the exception has happened.
8879
8980Lazarus tells you pretty much nothing about what actually happened. Valgrind will give you lots of details. To get these details you can either take a look into Valgrind trace file itself. But more convenient is to load the trace file into IDE. Select menu View -\> Leaks and Traces Open valgrind.trc
9081
91-<figure>
9282<img src="valgrind_trace.png" title="valgrind_trace.png" width="800" />
93-<figcaption>valgrind_trace.png</figcaption>
94-</figure>
9583
9684Here you can see the errors descriptions and three call stacks for each error: for the place where the exception happened, where the memory was freed and where it was allocated. All this is especially helpful for bug fixing. Select a line, double click and Lazarus will open a file and position cursor at a line in question.
9785
9886## Other suggestions
9987
10088Sometimes it can be still unclear if some memory misuse or a leak happened inside RTL or OS binaries. You can compile RTL with debugging info for Valgrind and without optimization. Please refer to FPC Wiki how to rebuild RTL.
10189
10290In some cases Valgrind can generate so called false positives. For example, a small variable was allocated in stack.
10391
10492``` pascal
10593var A2: array[2] of char;
10694```
10795
10896Then the variable was populated from a file and then compared to a constant
10997
11098``` pascal
11199 if A2 = 'AA' then ...
112100```
113101
114102FPC may choose to use MMX instructions for the comparison and allocates 16 bytes block for it, populating just first 2 bytes from the variable. Valgrind may detect it as an error of reading from uninitialized block. Technically it is correct - only two bytes were initialized, and the rest 14 bytes of the alignment block were not initialized but still scanned by MMX instruction. FPC is aware of this, it will mask the result and never use the result of the scan from masked bytes. But Valgrind still treats this as an error. As soon as bytes were allocated and scanned - it is access to uninitialized memory block.
115103
116104You can suppress reporting for such logical false positives and for other issues in OS or 3-rd party binaries like GTK, X11, etc, to concentrate more on your code. Please refer to Valgrind documentation regarding suppressions.
117105
118106## See also
119107
120108- [[GDB Debugger Tips|General tips/info on debugging]]
121109
122110---
123111*From the Free Pascal wiki, page "Debugging with Valgrind", as it stood on 2020-03-06 after a change by Mm7, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history