[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