There's no guarantee that valgrind will pick up anything, but it very well might uncover e.g. a hidden memory corruption bug that sometimes causes a segfault further down the line.
Besides, basic usage of valgrind isn't nearly as complicated as the wiki makes it out to be:
- Install valgrind with sudo apt install valgrind
- Check the -gv (Generate code for valgrind) option in the project settings and recompile
- Run your program like so: valgrind ./azul487
Because that sounded promising I tried valgrind for my very 1st time. But it took plenty of hours without getting a result. Maybe valgrind needs much more effort to learn it and to customize / configurate it in a reasonable way for each individual program and purpose...
Here comes a short extract of typically results of many runs:
Example 1:valgrind --log-file=vg01.trc /hg/utis/azul
I only started my program and exited it
immediately via the Close-Button.
Valgrind reported
10x "Conditional jump or move depends on uninitialised value(s)" and a summary of:
HEAP SUMMARY:
in use at exit: 2,168,819 bytes in 30,420 blocks
total heap usage: 503,830 allocs, 473,410 frees, 43,368,298 bytes allocated
LEAK SUMMARY:
definitely lost: 14,550 bytes in 47 blocks
indirectly lost: 156,052 bytes in 6,420 blocks
possibly lost: 20,470 bytes in 53 blocks
still reachable: 1,834,179 bytes in 22,731 blocks
suppressed: 0 bytes in 0 blocks
Rerun with --leak-check=full to see details of leaked memory
Use --track-origins=yes to see where uninitialised values come from
For lists of detected and suppressed errors, rerun with: -s
ERROR SUMMARY: 158 errors from 10 contexts (suppressed: 0 from 0)
This sounds not good...
I checked the 1st complaint:
Conditional jump or move depends on uninitialised value(s)
at 0x41F8B4: SYSTEM_$$_INDEXBYTE$formal$INT64$BYTE$$INT64 (in /hg/utis/azul)
by 0x464BE2: LIB_$$_REPL_5C_ZVS$ANSISTRING$$ANSISTRING (lib.pas:2558)
by 0x46963C: LIB_$$_UTF8_ZVS$ANSISTRING$$ANSISTRING (lib.pas:3512)
by 0x4B359C: LCLLIB_$$_SETTOOLTIP$TCONTROL$ANSISTRING (LCLlib.pas:6550)
by 0x4B2DD9: LCLLIB_$$_SETLABELEX$TLABEL$SMALLINT$ANSISTRING$$SMALLINT (LCLlib.pas:6413)
by 0x51FFB6: AZUL1$_$TFORM1_$__$$_SET_ALL_POSITIONS$BOOLEAN$S40 (azul1.pas:20115)
by 0x52AC3E: AZUL1$_$TFORM1_$__$$_FORMCREATE$TOBJECT (azul1.pas:21943)
by 0x44C4B6: FORMS$_$TCUSTOMFORM_$__$$_DOCREATE (customform.inc:939)
by 0x44A12C: FORMS$_$TCUSTOMFORM_$__$$_AFTERCONSTRUCTION (customform.inc:149)
by 0x452CA3: FORMS$_$TFORM_$__$$_CREATE$TCOMPONENT$$TFORM (customform.inc:3184)
by 0x45CFC4: FORMS$_$TAPPLICATION_$__$$_CREATEFORM$TCOMPONENTCLASS$formal (application.inc:2239)
by 0x41F1BC: main (azul.pas:976)
The top most line in my sources is lib.pas:2558 which has:
type ansi = ansistring;
function repl_5C_ZVS(s: ansi): ansi;
{replaces '\' by 'LineEnding'}
begin
exit(strreplS_A(s,'\',LineEnding)); // this is line 2558
end;
function strreplS_A(s: ansi; alt,neu: ansi): ansi;
{replaces in 's' all occurrences of 'alt' by 'neu'}
var p: longint;
begin
p:=1;
repeat p:=strutils.PosEx(alt,s,p);
if p=0 then exit(s); {if not found}
delete(s,p,length(alt));
insert(neu,s,p);
inc(p,length(neu));
until false;
end;
I can't find there a "Conditional jump or move depends on uninitialised value(s)"...
The other 9 complaints all lead also to a usage of above function strreplS_A().
I don't see how this can help me, because I get many complaints for the
same source reason and can't find there something wrong.
Example 2:valgrind --leak-check=full --log-file=vg02.trc /hg/utis/azul
I only started my program and exited it
immediately via the Close-Button.
Additional to above 10 complaints valgrind now reported this 22 complaints:
8 bytes in 1 blocks are definitely lost in loss record 407 of 9,037
8 bytes in 1 blocks are definitely lost in loss record 408 of 9,037
24 bytes in 1 blocks are definitely lost in loss record 2,593 of 9,037
34 bytes in 1 blocks are definitely lost in loss record 4,099 of 9,037
40 bytes in 1 blocks are definitely lost in loss record 4,461 of 9,037
48 (24 direct, 24 indirect) bytes in 1 blocks are definitely lost in loss record 5,077 of 9,037
84 bytes in 1 blocks are definitely lost in loss record 6,392 of 9,037
112 (80 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 7,888 of 9,037
128 bytes in 1 blocks are definitely lost in loss record 8,027 of 9,037
232 (40 direct, 192 indirect) bytes in 1 blocks are definitely lost in loss record 8,333 of 9,037
320 (256 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 8,458 of 9,037
432 (184 direct, 248 indirect) bytes in 1 blocks are definitely lost in loss record 8,568 of 9,037
520 bytes in 13 blocks are definitely lost in loss record 8,631 of 9,037
578 (184 direct, 394 indirect) bytes in 1 blocks are definitely lost in loss record 8,668 of 9,037
795 (136 direct, 659 indirect) bytes in 1 blocks are definitely lost in loss record 8,717 of 9,037
14,402 (1,024 direct, 13,378 indirect) bytes in 2 blocks are definitely lost in loss record 9,012 of 9,037
15,631 (512 direct, 15,119 indirect) bytes in 1 blocks are definitely lost in loss record 9,016 of 9,037
15,631 (512 direct, 15,119 indirect) bytes in 1 blocks are definitely lost in loss record 9,017 of 9,037
15,631 (512 direct, 15,119 indirect) bytes in 1 blocks are definitely lost in loss record 9,018 of 9,037
26,557 (7,680 direct, 18,877 indirect) bytes in 10 blocks are definitely lost in loss record 9,030 of 9,037
31,823 (1,024 direct, 30,799 indirect) bytes in 2 blocks are definitely lost in loss record 9,032 of 9,037
47,454 (1,536 direct, 45,918 indirect) bytes in 3 blocks are definitely lost in loss record 9,034 of 9,037
E.g. the last one (which has the largest amout of lost bytes) contains:
47,454 (1,536 direct, 45,918 indirect) bytes in 3 blocks are definitely lost in loss record 9,034 of 9,037
at 0xD339B80: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0xE1B08AA: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.1)
by 0xE1B4ED8: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.1)
by 0xDCDF88B: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11800.0)
by 0xDFB48C7: ??? (in /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0.5200.1)
by 0xE42655D: ??? (in /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0.5200.1)
by 0xDBE0AD7: ??? (in /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0.5200.1)
by 0xDBF4FAD: ??? (in /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0.5200.1)
by 0xDBEA08D: ??? (in /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0.5200.1)
by 0xDFB5A88: ??? (in /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0.5200.1)
by 0xDBF3A74: ??? (in /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0.5200.1)
by 0xDBF45C7: ??? (in /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0.5200.1)
but contains not even 1 line of my sources.
Another example, which contains not even 1 line of my sources:
336 bytes in 1 blocks are possibly lost in loss record 8,467 of 9,037
at 0xD339953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0xCB005AB: calloc (rtld-malloc.h:44)
by 0xCB005AB: allocate_dtv (dl-tls.c:370)
by 0xCB005AB: _dl_allocate_tls (dl-tls.c:629)
by 0xDE38616: allocate_stack (allocatestack.c:429)
by 0xDE38616: pthread_create@@GLIBC_2.34 (pthread_create.c:655)
by 0xDB2678E: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
by 0xDAEEB5E: g_thread_new (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
by 0xDAC9B29: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0)
by 0xE071FA5: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.8000.0)
by 0xE072064: g_task_get_type (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.8000.0)
by 0xE0DFAD8: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.8000.0)
by 0xE0D29D4: g_bus_get_sync (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.8000.0)
by 0x1182833D: ??? (in /usr/lib/x86_64-linux-gnu/gio/modules/libgvfsdbus.so)
In all 22 complaints there is only 1 single one, which contains at all lines of my sources:
8 bytes in 1 blocks are definitely lost in loss record 408 of 9,037
at 0xD332828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x4445FC: CMEM_$$_CGETMEM$QWORD$$POINTER (in /hg/utis/azul)
by 0x7D2E09: PROPERTYSTORAGE$_$TCUSTOMPROPERTYSTORAGE_$__$$_SAVE (propertystorage.pas:536)
by 0x452F10: FORMS$_$TFORMPROPERTYSTORAGE_$__$$_FORMCLOSE$TOBJECT$TCLOSEACTION (customform.inc:3270)
by 0x44C5D1: FORMS$_$TCUSTOMFORM_$__$$_DOCLOSE$TCLOSEACTION (customform.inc:962)
by 0x4501AB: FORMS$_$TCUSTOMFORM_$__$$_CLOSE (customform.inc:2196)
by 0x52B300: AZUL1_$$_FORM1_CLOSE (azul1.pas:22091)
by 0x5169EB: AZUL1$_$TFORM1_$__$$_BUTTON_ENDECLICK$TOBJECT (azul1.pas:18111)
by 0x620285: CONTROLS$_$TCONTROL_$__$$_CLICK (control.inc:2911)
by 0x686399: STDCTRLS$_$TBUTTONCONTROL_$__$$_CLICK (buttoncontrol.inc:55)
by 0x686C50: STDCTRLS$_$TCUSTOMBUTTON_$__$$_CLICK (buttons.inc:169)
by 0x686265: STDCTRLS$_$TBUTTONCONTROL_$__$$_WMDEFAULTCLICKED$TLMESSAGE (buttoncontrol.inc:21)
The 2 referenced procedures are:
procedure TForm1.Button_EndeClick(Sender: TObject);
{Button "End" closes the program}
var stop: boolean;
begin
stop:=ask_vor_ProgEnde_stop; {asks if really wants to terminate}
if not stop then exit; {if no}
Form1_Close; // this is line 18111
end;
procedure Form1_Close;
{closes the program}
begin
ask_in_FormCloseQuery:=false; {disable a query dialog in the OnClose Event}
Form1.Close; {closes the program} // this is line 22091
end;
The top most line in this complaint, wherefore a source line was found, is this procedure in <installdir>/lazarus/lcl/propertystorage.pas:
procedure TCustomPropertyStorage.Save;
begin
if Active and not (csDesigning in ComponentState) then begin
StorageNeeded(False);
Try
if Assigned(FOnSavingProperties) then
FOnSavingProperties(Self);
try
SaveProperties; // this is line 536
FStoredValues.SaveValues;
NotifyLinks(poSave);
if Assigned(FOnSaveProperties) then
FOnSaveProperties(Self);
FSaved := True;
except
on E: Exception do
begin
if Assigned(FOnSaveException) then
FOnSaveException(Self, E.ClassName, E.Message);
end;
end;
Finally
FreeStorage;
end;
end;
end;
I don't see how this can help me, because I get many complaints, which (except from 1 single one) contain not even 1 line of my sources, and in this single exception I can't find something wrong.
Example 3:valgrind --leak-check=full --log-file=vg03.trc /hg/utis/azul
This time I played for 8 minutes with my program and used several features (when the AV occured 1 week ago, I had used the program for 83 minutes). The output of valgrind had > 2100 lines and ended with
ERROR SUMMARY: 1155 errors from 145 contextswhich is so huge, that this is not manageable, especially if after each very time consuming analysis I can't see a real bug.
Do I something wrong?
Of course I read
https://wiki.freepascal.org/Debugging_with_Valgrind.
And I took a look at "valgrind --help" and "man valgrind" and
https://valgrind.org, but in a reliable time it didn't help me.
As said, the AV last week occured during termination of the program after 83 minutes. Of course I can't remember, which features in what variantes or combinations or in which order I used and which error dialogs had been involved in which situations.
I fear, that valgrind might find the root cause only, ifa) it's source position is really called again at all and
b) if all neccessary "conditions" are met.
And when the output of valgrind grows more and more when using my program longer - and most of it's complaints waste only time, because there is no bug - how should I find any real bug?
Of course it would be great to find the root cause for the AV, but because (until now) it occured only once after more than 1 year and "only" during the termination of the program, I don't want to spent too much time for it.
Has someone an idea of only adding some ingenious parameters for valgrind to reduce it's output to show only real bugs, which could cause an AV?