Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2005-08

According to Valgrind, something is wrong in IndexByte

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Micha Nelissen

Hi,

In TDbf I use MemScan, which is defined as such: (FPC_DISABLE for testing, normally FPC)

<code>
{$ifdef FPC_DISABLE}
function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer;
var
  I: Integer;
begin
  I := System.IndexByte(Buffer, Length, Chr);
  if I = -1 then
    Result := nil
  else
    Result := Buffer+I;
end;
{$else}

function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; asm
PUSH EDI
MOV EDI,Buffer
MOV AL, Chr
MOV ECX,Length
REPNE SCASB
MOV EAX,0
JNE @@1
MOV EAX,EDI
DEC EAX
@@1: POP EDI
end;

{$endif}
</code>

So you see, it's IndexByte with a tweak. If I'm using the FPC version, implemented using IndexByte Valgrind reports a lot of errors like so:

==13664== 44439 errors in context 34 of 34:
==13664== Conditional jump or move depends on uninitialised value(s) ==13664== at 0x80537C9: SYSTEM_INDEXBYTE$formal$LONGINT$BYTE$$LONGINT (i386.inc:312) ==13664== by 0x81C3B28: DBF_COMMON_MEMSCAN$POINTER$BYTE$LONGINT$$POINTER (dbf_common.pas:433) ==13664== by 0x81E51C2: DBF_MEMO_TMEMOFILE_$__READMEMO$LONGINT$TSTREAM (dbf_memo.pas:278) ==13664== by 0x81C6763: DBF_DBFFILE_TDBFFILE_$__RESTRUCTURETABLE$TDBFFIELDDEFS$BOOLEAN (dbf_dbffile.pas:1303) ==13664== by 0x81AD8B4: DBF_TDBF_$__PACKTABLE (dbf.pas:1521)

But if I use my own version (which I use for delphi and is i386 specific), it reports no errors in this location, for Dbf_Common/Dbf_Memo.

i386 IndexByte seems way more complex than my custom MemScan, but maybe that's necessary somehow.

Micha

Reply by email

Jan Ruzicka
to Micha Nelissen
Micha Nelissen wrote 64 lines
Hi, In TDbf I use MemScan, which is defined as such: (FPC_DISABLE for testing, normally FPC) <code> {$ifdef FPC_DISABLE} function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; var I: Integer; begin I := System.IndexByte(Buffer, Length, Chr); if I = -1 then Result := nil else Result := Buffer+I; end; {$else} function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer; asm PUSH EDI MOV EDI,Buffer MOV AL, Chr MOV ECX,Length REPNE SCASB MOV EAX,0 JNE @@1 MOV EAX,EDI DEC EAX @@1: POP EDI end; {$endif} </code> So you see, it's IndexByte with a tweak. If I'm using the FPC version, implemented using IndexByte Valgrind reports a lot of errors like so: ==13664== 44439 errors in context 34 of 34: ==13664== Conditional jump or move depends on uninitialised value(s) ==13664== at 0x80537C9: SYSTEM_INDEXBYTE$formal$LONGINT$BYTE$$LONGINT (i386.inc:312) ==13664== by 0x81C3B28: DBF_COMMON_MEMSCAN$POINTER$BYTE$LONGINT$$POINTER (dbf_common.pas:433) ==13664== by 0x81E51C2: DBF_MEMO_TMEMOFILE_$__READMEMO$LONGINT$TSTREAM (dbf_memo.pas:278) ==13664== by 0x81C6763: DBF_DBFFILE_TDBFFILE_$__RESTRUCTURETABLE$TDBFFIELDDEFS$BOOLEAN (dbf_dbffile.pas:1303) ==13664== by 0x81AD8B4: DBF_TDBF_$__PACKTABLE (dbf.pas:1521) But if I use my own version (which I use for delphi and is i386 specific), it reports no errors in this location, for Dbf_Common/Dbf_Memo. i386 IndexByte seems way more complex than my custom MemScan, but maybe that's necessary somehow. Micha

Have you investigated more into the Valgrind behavior? The jump (JNE @@1) is reacting to "REPNE SCASB" and all values seem to be defined.
Valgrind may be expecting some numerical operation to set the flags. "Flags Affected: None; however, the CMPS and SCAS instructions do set the status flags in the EFLAGS register."
Intel: "IA-32 Intel Architecture Software Developer’s Manual" IA-32-2b.pdf

Jan

Reply by email

Micha Nelissen
to Jan Ruzicka
Show quoted text 15 lines
On Aug 12, 2005, at 05:04, Micha Nelissen wrote: > But if I use my own version (which I use for delphi and is i386 > specific), it reports no errors in this location, for > Dbf_Common/Dbf_Memo. > > i386 IndexByte seems way more complex than my custom MemScan, but > maybe that's necessary somehow. Have you investigated more into the Valgrind behavior? The jump (JNE @@1) is reacting to "REPNE SCASB" and all values seem to be defined. Valgrind may be expecting some numerical operation to set the flags. "Flags Affected: None; however, the CMPS and SCAS instructions do set the status flags in the EFLAGS register."

Hmm is your point that valgrind should detect an error in my "REPNE SCASB" ?

I am not familiar with the internals of valgrind, so to conclude from 1 hour valgrind-experience that valgrind is faulty would be a little over the top IMHO...

Micha

Reply by email

Jan Ruzicka
to Micha Nelissen
Micha Nelissen wrote 22 lines
On Sat, 13 Aug 2005 00:03:01 -0400 Jan Ruzicka wrote: > On Aug 12, 2005, at 05:04, Micha Nelissen wrote: > >> But if I use my own version (which I use for delphi and is i386 >> specific), it reports no errors in this location, for >> Dbf_Common/Dbf_Memo. >> >> i386 IndexByte seems way more complex than my custom MemScan, but >> maybe that's necessary somehow. > > Have you investigated more into the Valgrind behavior? > The jump (JNE @@1) is reacting to "REPNE SCASB" and all values > seem > to be defined. > Valgrind may be expecting some numerical operation to set the flags. > "Flags Affected: None; however, the CMPS and SCAS instructions do set > the status flags in the EFLAGS register." Hmm is your point that valgrind should detect an error in my "REPNE SCASB" ?

No. Sorry did not read the original post carefully enough. My understanding was that the assembler portion was causing valgrind to complain.
Now I finally got it. You were pointing out possible problem in System.IndexByte(Buffer, Length, Chr);

The valgrind message is really strange, because the IndexByte function is really similar to one you advised.

The svn version has this in rtl/i386/i386.inc

     297 function IndexByte(Const buf;len:SizeInt;b:byte):SizeInt;

assembler;
298 var

     299   saveedi,saveebx : longint;
     300 asm
     301         movl    %edi,saveedi
     302         movl    %ebx,saveebx
     303         movl    buf,%edi       // Load String
     304         movb    b,%bl
     305         movl    len,%ecx       // Load len
     306         xorl    %eax,%eax
     307         testl   %ecx,%ecx
     308         jz      .Lcharposnotfound
     309         cld
     310         movl    %ecx,%edx      // Copy for easy manipulation
     311         movb    %bl,%al
     312         repne
     313         scasb
     314         jne     .Lcharposnotfound
     315         incl    %ecx
     316         subl    %ecx,%edx
     317         movl    %edx,%eax
     318         jmp     .Lready
     319 .Lcharposnotfound:
     320         movl    $-1,%eax
     321 .Lready:
     322         movl    saveedi,%edi
     323         movl    saveebx,%ebx
     324 end;
I am not familiar with the internals of valgrind, so to conclude from 1 hour valgrind-experience that valgrind is faulty would be a little over the top IMHO..

Once again sorry for the misunderstanding.

Jan

Reply by email