Hi all,
I have just started using valgrind, and I was surprised that I got a lot of errors, particularly in places that look like clean code. So I whittled things down and created a test program. Here is the error I am seeing (I've removed the procid, ==11180==):
Invalid read of size 16
at 0x401727: SYSTEM_INDEXBYTE$formal$INT64$BYTE$$INT64 (in /Docs/fpc/test/vg_stringlist_const_error)
by 0x40053B: main (vg_stringlist_const_error.pas:20) Address 0xbfdb6c0 is 16 bytes inside a block of size 30 alloc'd at 0x4C28C20: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x4206A6: CMEM_CGETMEM$QWORD$$POINTER (in
/Docs/fpc/test/vg_stringlist_const_error)
by 0x42BF17: CLASSES_TSTRINGS_$__GETVALUE$ANSISTRING$$ANSISTRING (in /Docs/fpc/test/vg_stringlist_const_error)
by 0x400532: main (vg_stringlist_const_error.pas:20)
Here is the test program:
program vg_stringlist_const_error;
uses
classes, sysutils;
const
list_key = 'foo';
some_directory_that_exists = '.';
var
sl : TStringList;
fa : longint;
begin
sl := TStringList.Create;
sl.add (list_key + '=' + some_directory_that_exists);
writeln;
writeln ('----- VALGRIND INVALID READ HAPPENS HERE -----');
writeln;
fa := FileGetAttr (sl.Values[list_key]);
writeln;
writeln ('----- done -----');
writeln;
freeandnil (sl);
end.I am compiling with -n so as to avoid any variability from /etc/fpc.cfg, like so:
fpc -n -Fu'/usr/lib/fpc/$fpcversion/units/$fpctarget/*' -gv vg_stringlist_const_error.pas
then,
valgrind ./vg_stringlist_const_error
I'm using debian linux, 64-bit, and have seen the error on three different computers, running debian 7 & 8 (wheezy/oldstable and jessie/stable), and using fpc 2.6.2 and 2.6.4; and using valgrind 3.7.0 and 3.10.0
Some notes/observations from testing:
- With the TStringList, if I use sl.Add ('.') and sl.Strings[0] to get the same value '.' the error does not occur. It only happens when I use sl.Values
- The fact that FileGetAttr uses a const variable is relevant; if I have a function that receives sl.Values['foo'] as a call-by-value variable, then passes that to FileGetAttr, the error does not occur.
- If the directory (or file) does not exist then the error does not occur.
- Even if the file/directory does exist, the error does not occur for certain files/dirs. I haven't yet figured out what it's sensitive to, but most existing files/dirs/links seem to trigger the error.
- If I declare a local ansistring variable and assign sl.Values['foo'] to that var, then pass it to FileGetAttr, it doesn't make a difference, the error still occurs. Ditto if the local variable is e.g. string[10], although the trace is slightly different, the invalid read is still there.
Alright, can't think of anything else to add at the moment... any thoughts?
Thanks,
David
