[fpc-pascal] valgrind: "invalid read"
David Emerson
dle3ab at angelbase.com
Thu Jun 4 01:51:16 CEST 2015
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
More information about the fpc-pascal
mailing list