Probleme mit code unter 64bit cpu

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Reinhard
Beiträge: 46
Registriert: Fr 26. Sep 2008, 16:56

Probleme mit code unter 64bit cpu

Beitrag von Reinhard »

Hallo,

Ein kleines aber ziemlich lästiges Problem ist hier aufgetreten :

Ich habe einen code zum errechnen der md5 summe (stammt noch aus Delphi 4.x) Zeiten und wurde nur auf FP/Lazarus angepasst.

Jedenfalls funktioniert der Code korrekt bei einer 32bit CPU.

Wenn ich den Code unter einer 64bit cpu laufen lasse (kompiliert auf einer 64bit cpu - egal ob windows oder linux) funktioniert er auch soweit, nur wenn eine
Datei größer als 2gb ist wird eine falsche prüfsumme errechnet.

Ich bin da jetzt wirklich ratlos wie es dazu kommen kann, da es eben wie gesagt korrekt unter 32bit funktioniert.

Code: Alles auswählen

 
program project1;
 
 
 
{$mode objfpc}{$H+}
 
Uses
  SysUtils,Classes,LazUTF8Classes;
 
 
Type
  TDigestStr = String[32];
  TDigest = Array[0..15] Of Byte;
  TDigestLongWord = Array[0..3] Of LongWord;
 
  TLongWordBuf = Array[0..15] Of LongWord;
  TByteBuf = Array[0..63] Of Byte;
 
  TCustomMD5 = class(TObject)
  Private
    FDigest: TDigest;         {the digest to be returned}
    CDigest: TDigestLongWord;  {digest accumulator}
    BitLo, BitHi: LongWord;    { number of _bits_ handled mod 2^64 }
    bBuf: TByteBuf;
    bLen: Cardinal; {bytes in bBuf}
    BufferChanged: Boolean;
 
    Procedure ResetBuffer;
    Procedure Update (Const ChkBuf; Len: Cardinal);
    Function GetDigest: TDigest;
    Function GetDigestStr: TDigestStr;
    Function GetDigestLongWord: TDigestLongWord;
  Protected
    { Protected declarations }
  Public
    Constructor Create;
    Property Digest: TDigest Read GetDigest;
    Property DigestLongWord: TDigestLongWord Read GetDigestLongWord;
    Property DigestStr: TDigestStr Read GetDigestStr;
 
  End;
 
  TMD5 = Class(TCustomMD5)
  Public
    Procedure Reset;
    Procedure Add (Value: Char); Overload;
    Procedure Add (Value: Byte); Overload;
    Procedure Add (Value: Word); Overload;
    Procedure Add (Value: Integer); Overload;
    Procedure Add (Value: Cardinal); Overload;
    Procedure Add (Const Value: String); Overload;
    Procedure Add (Value: TStrings); Overload;
    Function AddFile (Value: String):Longint;
  End;
 
 
 
 
Procedure Transform (Var Accu; Const Buf);
Var
  a, b, c, d: LongWord;
  lBuf: TLongWordBuf Absolute Buf;
  lAccu: TDigestLongWord Absolute Accu;
 
  Function ROL (x: LongWord; n: LongWord): LongWord;
  Begin Result:= (x Shl n) Or (x Shr (32-n)) End;
 
  Function FF (a,b,c,d,x,s,ac: LongWord): LongWord;
  Begin Result:= ROL (a+x+ac + (b And c Or Not b And d), s) + b End;
 
  Function GG (a,b,c,d,x,s,ac: LongWord): LongWord;
  Begin Result:= ROL (a+x+ac + (b And d Or c And Not d), s) + b End;
 
  Function HH (a,b,c,d,x,s,ac: LongWord): LongWord;
  Begin Result:= ROL (a+x+ac + (b Xor c Xor d), s) + b End;
 
  Function II (a,b,c,d,x,s,ac: LongWord): LongWord;
  Begin Result:= ROL (a+x+ac + (c Xor (b Or Not d)), s) + b End;
 
Begin
  a:= lAccu[0];
  b:= lAccu[1];
  c:= lAccu[2];
  d:= lAccu[3];
 
  a:= FF(a,b,c,d, lBuf[ 0],  7, $d76aa478); { 1 }
  d:= FF(d,a,b,c, lBuf[ 1], 12, $e8c7b756); { 2 }
  c:= FF(c,d,a,b, lBuf[ 2], 17, $242070db); { 3 }
  b:= FF(b,c,d,a, lBuf[ 3], 22, $c1bdceee); { 4 }
  a:= FF(a,b,c,d, lBuf[ 4],  7, $f57c0faf); { 5 }
  d:= FF(d,a,b,c, lBuf[ 5], 12, $4787c62a); { 6 }
  c:= FF(c,d,a,b, lBuf[ 6], 17, $a8304613); { 7 }
  b:= FF(b,c,d,a, lBuf[ 7], 22, $fd469501); { 8 }
  a:= FF(a,b,c,d, lBuf[ 8],  7, $698098d8); { 9 }
  d:= FF(d,a,b,c, lBuf[ 9], 12, $8b44f7af); { 10 }
  c:= FF(c,d,a,b, lBuf[10], 17, $ffff5bb1); { 11 }
  b:= FF(b,c,d,a, lBuf[11], 22, $895cd7be); { 12 }
  a:= FF(a,b,c,d, lBuf[12],  7, $6b901122); { 13 }
  d:= FF(d,a,b,c, lBuf[13], 12, $fd987193); { 14 }
  c:= FF(c,d,a,b, lBuf[14], 17, $a679438e); { 15 }
  b:= FF(b,c,d,a, lBuf[15], 22, $49b40821); { 16 }
 
  a:= GG(a,b,c,d, lBuf[ 1],  5, $f61e2562); { 17 }
  d:= GG(d,a,b,c, lBuf[ 6],  9, $c040b340); { 18 }
  c:= GG(c,d,a,b, lBuf[11], 14, $265e5a51); { 19 }
  b:= GG(b,c,d,a, lBuf[ 0], 20, $e9b6c7aa); { 20 }
  a:= GG(a,b,c,d, lBuf[ 5],  5, $d62f105d); { 21 }
  d:= GG(d,a,b,c, lBuf[10],  9, $02441453); { 22 }
  c:= GG(c,d,a,b, lBuf[15], 14, $d8a1e681); { 23 }
  b:= GG(b,c,d,a, lBuf[ 4], 20, $e7d3fbc8); { 24 }
  a:= GG(a,b,c,d, lBuf[ 9],  5, $21e1cde6); { 25 }
  d:= GG(d,a,b,c, lBuf[14],  9, $c33707d6); { 26 }
  c:= GG(c,d,a,b, lBuf[ 3], 14, $f4d50d87); { 27 }
  b:= GG(b,c,d,a, lBuf[ 8], 20, $455a14ed); { 28 }
  a:= GG(a,b,c,d, lBuf[13],  5, $a9e3e905); { 29 }
  d:= GG(d,a,b,c, lBuf[ 2],  9, $fcefa3f8); { 30 }
  c:= GG(c,d,a,b, lBuf[ 7], 14, $676f02d9); { 31 }
  b:= GG(b,c,d,a, lBuf[12], 20, $8d2a4c8a); { 32 }
 
  a:= HH(a,b,c,d, lBuf[ 5],  4, $fffa3942); { 33 }
  d:= HH(d,a,b,c, lBuf[ 8], 11, $8771f681); { 34 }
  c:= HH(c,d,a,b, lBuf[11], 16, $6d9d6122); { 35 }
  b:= HH(b,c,d,a, lBuf[14], 23, $fde5380c); { 36 }
  a:= HH(a,b,c,d, lBuf[ 1],  4, $a4beea44); { 37 }
  d:= HH(d,a,b,c, lBuf[ 4], 11, $4bdecfa9); { 38 }
  c:= HH(c,d,a,b, lBuf[ 7], 16, $f6bb4b60); { 39 }
  b:= HH(b,c,d,a, lBuf[10], 23, $bebfbc70); { 40 }
  a:= HH(a,b,c,d, lBuf[13],  4, $289b7ec6); { 41 }
  d:= HH(d,a,b,c, lBuf[ 0], 11, $eaa127fa); { 42 }
  c:= HH(c,d,a,b, lBuf[ 3], 16, $d4ef3085); { 43 }
  b:= HH(b,c,d,a, lBuf[ 6], 23, $04881d05); { 44 }
  a:= HH(a,b,c,d, lBuf[ 9],  4, $d9d4d039); { 45 }
  d:= HH(d,a,b,c, lBuf[12], 11, $e6db99e5); { 46 }
  c:= HH(c,d,a,b, lBuf[15], 16, $1fa27cf8); { 47 }
  b:= HH(b,c,d,a, lBuf[ 2], 23, $c4ac5665); { 48 }
 
  a:= II(a,b,c,d, lBuf[ 0],  6, $f4292244); { 49 }
  d:= II(d,a,b,c, lBuf[ 7], 10, $432aff97); { 50 }
  c:= II(c,d,a,b, lBuf[14], 15, $ab9423a7); { 51 }
  b:= II(b,c,d,a, lBuf[ 5], 21, $fc93a039); { 52 }
  a:= II(a,b,c,d, lBuf[12],  6, $655b59c3); { 53 }
  d:= II(d,a,b,c, lBuf[ 3], 10, $8f0ccc92); { 54 }
  c:= II(c,d,a,b, lBuf[10], 15, $ffeff47d); { 55 }
  b:= II(b,c,d,a, lBuf[ 1], 21, $85845dd1); { 56 }
  a:= II(a,b,c,d, lBuf[ 8],  6, $6fa87e4f); { 57 }
  d:= II(d,a,b,c, lBuf[15], 10, $fe2ce6e0); { 58 }
  c:= II(c,d,a,b, lBuf[ 6], 15, $a3014314); { 59 }
  b:= II(b,c,d,a, lBuf[13], 21, $4e0811a1); { 60 }
  a:= II(a,b,c,d, lBuf[ 4],  6, $f7537e82); { 61 }
  d:= II(d,a,b,c, lBuf[11], 10, $bd3af235); { 62 }
  c:= II(c,d,a,b, lBuf[ 2], 15, $2ad7d2bb); { 63 }
  b:= II(b,c,d,a, lBuf[ 9], 21, $eb86d391); { 64 }
 
  Inc(lAccu[0], a);
  Inc(lAccu[1], b);
  Inc(lAccu[2], c);
  Inc(lAccu[3], d)
End;
 
Constructor TCustomMD5.Create;
Begin
  Inherited Create;
  ResetBuffer;
End;
 
Procedure TCustomMD5.ResetBuffer;
Begin
  BitLo:= 0;
  BitHi:= 0;
  bLen:= 0;
  {Load magic initialization constants.}
  CDigest[0]:= $67452301;
  CDigest[1]:= $efcdab89;
  CDigest[2]:= $98badcfe;
  CDigest[3]:= $10325476;
  BufferChanged:= True
End;
 
Procedure TCustomMD5.Update (Const ChkBuf; Len: Cardinal);
Var
  BufPtr: ^Byte;
  Left: Cardinal;
Begin
  BufferChanged:= True;
  If BitLo + LongWord(Len) Shl 3 < BitLo Then
    Inc(BitHi);
  Inc(BitLo, LongWord(Len) Shl 3);
  Inc(BitHi, LongWord(Len) Shr 29);
 
  BufPtr:= @ChkBuf;
  If bLen>0 Then Begin
    Left:= 64-bLen; If Left>Len Then Left:= Len;
    Move(BufPtr^, bBuf[bLen], Left);
    Inc(bLen, Left); Inc(BufPtr, Left);
    If bLen<64 Then Exit;
    Transform(CDigest, bBuf);
    bLen:= 0;
    Dec(Len, Left)
  End;
  While Len>=64 Do Begin
    Transform(CDigest, BufPtr^);
    Inc(BufPtr, 64);
    Dec(Len, 64)
  End;
  If Len>0 Then Begin
    bLen:= Len;
    Move(BufPtr^, bBuf[0], bLen)
  End
End;
 
Function TCustomMD5.GetDigest: TDigest;
{-get digest without modifying bBuf, bLen and BitLo/Hi}
Var
  WorkBuf: TByteBuf;
  WorkLen: Cardinal;
Begin
  If BufferChanged Then Begin
    FDigest:= TDigest(CDigest);
    Move(bBuf, WorkBuf, bLen); {make copy of buffer}
    {pad out to block of form (0..55, BitLo, BitHi)}
    WorkBuf[bLen]:= $80;
    WorkLen:= bLen+1;
    If WorkLen>56 Then Begin
      FillChar(WorkBuf[WorkLen], 64-WorkLen, 0);
      TransForm(FDigest, WorkBuf);
      WorkLen:= 0
    End;
    FillChar(WorkBuf[WorkLen], 56-WorkLen, 0);
    TLongWordBuf(WorkBuf)[14]:= BitLo;
    TLongWordBuf(WorkBuf)[15]:= BitHi;
    Transform (FDigest, WorkBuf);
    BufferChanged:= False
  End;
  Result:= FDigest
End;
 
Function TCustomMD5.GetDigestStr: TDigestStr;
Const
  hc: Array[0..$F] Of Char = '0123456789ABCDEF';
Var
  aDigest: TDigest;
  i: 0..15;
Begin
  aDigest:= Digest;
  Result[0]:= #32;
  For i:= 0 To 15 Do Begin
    Result[1+i Shl 1]:= hc[aDigest[i] Shr 4];
    Result[2+i Shl 1]:= hc[aDigest[i] And $F]
  End
End;
 
Function TCustomMD5.GetDigestLongWord: TDigestLongWord;
Begin
  TDigest(Result):= Digest
End;
 
{ TMD5 }
 
Procedure TMD5.Reset;
Begin
  ResetBuffer
End;
 
Procedure TMD5.Add (Value: Char);
Begin
  Update(Value, SizeOf(Value))
End;
 
Procedure TMD5.Add (Value: Byte);
Begin
  Update(Value, SizeOf(Value))
End;
 
Procedure TMD5.Add (Value: Word);
Begin
  Update(Value, SizeOf(Value))
End;
 
Procedure TMD5.Add (Value: Integer);
Begin
  Update(Value, SizeOf(Value))
End;
 
Procedure TMD5.Add (Value: Cardinal);
Begin
  Update(Value, SizeOf(Value))
End;
 
Procedure TMD5.Add (Const Value: String);
Begin
  Update(PChar(Value)^, Length(Value));
End;
 
Procedure TMD5.Add (Value: TStrings);
Var
  i: Integer;
Begin
  For i:= 0 To Value.Count-1 Do
    Add(Value[i])
End;
 
Function TMD5.AddFile (Value: String):Longint;
var
  aBuf: Pointer;
  wRd: Cardinal;
  ChunkSize:Longint;
  md5Stream:TFileStreamUTF8;
 
 
Begin
 
     Chunksize:=65536;
  TRY
  GetMem(aBuf, ChunkSize);
  Try
        MD5Stream:=TFileStreamUTF8.Create(Value,fmOpenRead);            {Create stream and open file}
        Except Begin                                                        {check for exception on opening}
                     Writeln('Error opening file');
                     Result:=-1;
                     exit;
               end;
        end;
 
      Repeat
        wrd:=MD5Stream.Read(aBuf^,Chunksize);
        if wRd>0 then Update(aBuf^, wRd)
      Until wRd<ChunkSize;
       Result:=0;
  Finally
    FreeMem(aBuf, ChunkSize);
    MD5Stream.Free;
  End
End;
 
{ handy procedures }
 
 
Function GetMD5FromFile (Const FileName: TFileName;VAR aChecksum:String): longint;
Begin
  With TMD5.Create Do
  Try
    Result:=AddFile(FileName);
    aChecksum:=DigestStr;
  Finally
    Free
  End;
End;
 
Function StringMD5Digest (S: String): TDigestStr;
Begin
  With TMD5.Create Do
  Try
    Add(S);
    Result:= DigestStr
  Finally
    Free
  End
End;
 
 
VAR CHeckSum:String;
begin
      GetMD5FromFile('aFileName  ',Checksum);
      writeln(checksum);
end.
 
 


Alle Prüfsummen sind korrekt sofern die Datei nicht größer als 2 GB ist, habe es z.b. mit der Datei : "openSUSE-13.2-DVD-x86_64.iso" probiert welche unter : http://ftp.uni-erlangen.de/opensuse/dis ... table/iso/ erhältlich ist probiert.

Ich bekomme unter 64bit folgende Prüfsumme :

Code: Alles auswählen

 81F21E991D8BE4929AD9D71CC8F36628  
jedoch unter 32 bit (die Korrekte )

Code: Alles auswählen

 EDA0959A196776132AB9681FDF52CC3C
 
:



 

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Probleme mit code unter 64bit cpu

Beitrag von theo »

Hab's nicht genau angeschaut, aber du musst wahrscheinlich int64 bzw. QWord verwenden, statt Cardinal etc.

http://www.freepascal.org/docs-html/ref/refsu5.html

Reinhard
Beiträge: 46
Registriert: Fr 26. Sep 2008, 16:56

Re: Probleme mit code unter 64bit cpu

Beitrag von Reinhard »

theo hat geschrieben:Hab's nicht genau angeschaut, aber du musst wahrscheinlich int64 bzw. QWord verwenden, statt Cardinal etc.

http://www.freepascal.org/docs-html/ref/refsu5.html


Hab ich auch schon probiert, ändert aber nichts an der Sache.

Wenn das das Problem wäre, dürfte es auch unter 32bit nicht korrekt funktionieren, was es aber einwandfrei tut.

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Probleme mit code unter 64bit cpu

Beitrag von theo »

Reinhard hat geschrieben:Hab ich auch schon probiert, ändert aber nichts an der Sache.


Warum arbeitest du nicht sowieso mit dem auf Int64 und QWord angepassten Code?
Den brauchst du ja wahrscheinlich für größere Dateien ohnehin.

Oder anders gesagt: Wenn du das wirklich angepasst hast, warum postest du dann den "alten" Code?

Joz
Beiträge: 40
Registriert: Mo 27. Mai 2013, 13:16
OS, Lazarus, FPC: Arch Linux, OpenSuse 13.2, Lazarus 1.4
CPU-Target: AMD64
Wohnort: Berlin

Re: Probleme mit code unter 64bit cpu

Beitrag von Joz »

theo hat geschrieben:Den brauchst du ja wahrscheinlich für größere Dateien ohnehin.

Würde ich nicht unbedingt sagen. Er unterteilt ja einen FileStream (der ja auch mit sehr großen Dateien umgehen kann) in Chunks von 64 KiB Größe, für die Cardinal locker ausreicht, kombiniert mit Repeat-Until. Wenn das unter 32 Bit funktioniert, müsste das ja auch unter 64 Bit funktionieren.
Deshalb würde ich persönlich eher Annahmen, die der Code macht, mit WriteLn's prüfen. Wird die richtige Anzahl an Chunks genutzt? Wird korrekt mit dem Rest umgegangen? Sowas in der Richtung.

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Probleme mit code unter 64bit cpu

Beitrag von theo »

Joz hat geschrieben:
theo hat geschrieben:Den brauchst du ja wahrscheinlich für größere Dateien ohnehin.

Würde ich nicht unbedingt sagen. Er unterteilt ja einen FileStream (der ja auch mit sehr großen Dateien umgehen kann) in Chunks von 64 KiB Größe, für die Cardinal locker ausreicht, kombiniert mit Repeat-Until.


Ja, kann schon sein. Ich habe wie weiter oben gesagt, den Code nicht im Detail analysiert.
Aber wo sonst soll der Fehler liegen? FPC Version?

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Probleme mit code unter 64bit cpu

Beitrag von Antrepolit »

Und was ist mit den schon vorhadenen Funktionen?

http://wiki.freepascal.org/hash
Grüße, Antrepolit

care only if your os is really burning

Reinhard
Beiträge: 46
Registriert: Fr 26. Sep 2008, 16:56

Re: Probleme mit code unter 64bit cpu

Beitrag von Reinhard »

Antrepolit hat geschrieben:Und was ist mit den schon vorhadenen Funktionen?

http://wiki.freepascal.org/hash


Ja das ist eine Option wenn es nicht anders gehen sollte , habe ich auch schon Probiert, würde mich aber trotzdem interessieren woran das Problem liegt.

Reinhard
Beiträge: 46
Registriert: Fr 26. Sep 2008, 16:56

Re: Probleme mit code unter 64bit cpu

Beitrag von Reinhard »

theo hat geschrieben:
Joz hat geschrieben:
theo hat geschrieben:Den brauchst du ja wahrscheinlich für größere Dateien ohnehin.

Würde ich nicht unbedingt sagen. Er unterteilt ja einen FileStream (der ja auch mit sehr großen Dateien umgehen kann) in Chunks von 64 KiB Größe, für die Cardinal locker ausreicht, kombiniert mit Repeat-Until.


Ja, kann schon sein. Ich habe wie weiter oben gesagt, den Code nicht im Detail analysiert.
Aber wo sonst soll der Fehler liegen? FPC Version?


an der kann es auch nicht liegen leider.

Unter 32bit ist es egal welche fpc Version , 2.6.1 , 2.6.2 oder 2.6.4 funkt alles.

Unter 64bit habe ich es mit 2.6.2 und 2.6.4 probiert (selbe wie die 32bit) eben halt nur bis zur 2gb grenze.

Irgendwie eine komische Sache das ganze.

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Probleme mit code unter 64bit cpu

Beitrag von Antrepolit »

Reinhard hat geschrieben:
Antrepolit hat geschrieben:Und was ist mit den schon vorhadenen Funktionen?

http://wiki.freepascal.org/hash


Ja das ist eine Option wenn es nicht anders gehen sollte , habe ich auch schon Probiert, würde mich aber trotzdem interessieren woran das Problem liegt.

Sorry, aber ich werde nie verstehen, warum man das Rad immer neu erfinden muss, wenn's schon wunderbar rund läuft. Verwende Standard-Methoden, wenn diese funktionieren. Du implementierst ja auch keine neue If-Anweisung auf Assembler-Ebene.
Grüße, Antrepolit

care only if your os is really burning

BeniBela
Beiträge: 309
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Probleme mit code unter 64bit cpu

Beitrag von BeniBela »

Was du brauchst ist eine 2 G + 1 Byte Datei die nicht funktioniert, und dann vergleichst du die Werte aller Variablen in der 32 und 64 Bitversion.
Nach den ersten 2GB und nach dem letzten Byte



Antrepolit hat geschrieben:
Sorry, aber ich werde nie verstehen, warum man das Rad immer neu erfinden muss, wenn's schon wunderbar rund läuft.



Wenn Reinhards Quellcode hier noch aus Delphi 4 Zeiten stammt, sind wohl eher die fpc Funktionen das neu erfundene Rad

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Probleme mit code unter 64bit cpu

Beitrag von Antrepolit »

BeniBela hat geschrieben:Was du brauchst ist eine 2 G + 1 Byte Datei die nicht funktioniert, und dann vergleichst du die Werte aller Variablen in der 32 und 64 Bitversion.
Nach den ersten 2GB und nach dem letzten Byte



Antrepolit hat geschrieben:
Sorry, aber ich werde nie verstehen, warum man das Rad immer neu erfinden muss, wenn's schon wunderbar rund läuft.



Wenn Reinhards Quellcode hier noch aus Delphi 4 Zeiten stammt, sind wohl eher die fpc Funktionen das neu erfundene Rad

Haarspalterei. Wenn es funktionierende Standards gibt, sollte man sie verwenden. Und da macht es keinen Sinn, alten Code aus der Versenkung zu holen. Er hat damit Probleme, die lange gelöst wurden. Wenn man so programmiert, kann man es auch sein lassen. Schließlich muss man dann noch Fehler ausmerzen, die lange von anderen gelöst wurden. Lidtragende sind dann die Endbenutzer. Und die eigenen Probleme auf Endbenutzer abzuwälzen in FOrm von unzuverlässiger oder schlecht bedienbarere Software ist Kindergarten. Da kann man es auch sein lassen.

Hätte der Thread-Ersteller hier ein Doppel-Posting gemacht, hätte man ihn verschrieen. Da sein Anliegen ein lange gelöstes Problem ist, liegt hier implizit ein redundanter Post vor. Und warum hat ihn niemand auf die Stadard-Funktionen hingewiesen? Das hätte ihm einen Haufen Zeit gespart.
Grüße, Antrepolit

care only if your os is really burning

ruewa
Beiträge: 153
Registriert: Sa 12. Apr 2014, 14:43

Re: Probleme mit code unter 64bit cpu

Beitrag von ruewa »

Sei doch nicht so ungnädig, Antrepolit! Selbstverständlich kann man alten Code weiterverwenden, wenn er sich bewährt hat. Soweit ich Reinhard verstanden habe, wollte er schlicht und einfach ein funktionierendes Programm auf einem 64-Bit-Rechner installieren und hat dabei erstmal keine Probleme erwartet (hätte ich auch nicht. denn das ist ja gerade das Konzept von Write Once, Compile Anywhere). Hinterher ist man natürlich immer schlauer.

Jetzt gibt es allerdings ein recht mysteriöses Problem. Warum sollte ein 64-Bit-Rechner mit den vorhandenen Integer-Typen (nach außen!) anders umgehen als eine 32-Bit-Kiste? Ob es an den Datentypen liegt oder an sonstwas, jedenfalls ist die Möglichkeit nicht von der Hand zu weisen, daß Reinhard hier auf einen fpc-Bug gestoßen ist. Dem lohnt es sich schon nachzugehen!

Edit: Weil mir das Argument nicht einleuchtet:

theo hat geschrieben:... du musst wahrscheinlich int64 bzw. QWord verwenden, statt Cardinal etc.

Daß 64-Bit-Integers für eine 64-bit-CPU geeignete Typen sind, ist klar. Aber sind sie auch geeigneter? Für bestimmte Anwendungen sicherlich, aber generell? Warum sollte ein 64-Bit-System nicht in der Lage sein, mit den in der 32-Bit-Welt etablierten Datentypen genauso umzugehen wie eine 32-Bit-Architektur?

Noch weiter gefragt: Die 2-GB-Schallmauer ist ja die Bereichsgrenze der (vorzeichenbehafteten) 32-Bit-Ganzzahl. Was macht FPC auf einer 64-Bit-Maschine in dem Moment, wo in einem 32-Bit-Register ein Überlauf stattfinden würde? Das 64-Bit-Register lacht noch nicht mal darüber und zählt einfach weiter. Generiert FPC einen Code, der dies simuliert / überprüft? Wäre das dann der Fall, wenn man mit Bereichs- und/oder Überlaufs-Überprüfung kompiliert (Projekt/Projekteinstellungen/Debuggen bzw. -Cr/-Co)?

@Reinhard: In diese Richtung würde ich ehestens vermuten, allerdings konnte ich im Quelltext erstmal keinen Kandidaten für einen solchen Effekt ausmachen. Hast Du das Programm mal mit diesen Bereichs-/Überlaufsüberprüfungen kompiliert?

Gruß Rüdiger

Reinhard
Beiträge: 46
Registriert: Fr 26. Sep 2008, 16:56

Re: Probleme mit code unter 64bit cpu

Beitrag von Reinhard »

Antrepolit hat geschrieben:
BeniBela hat geschrieben:Was du brauchst ist eine 2 G + 1 Byte Datei die nicht funktioniert, und dann vergleichst du die Werte aller Variablen in der 32 und 64 Bitversion.
Nach den ersten 2GB und nach dem letzten Byte



Antrepolit hat geschrieben:
Sorry, aber ich werde nie verstehen, warum man das Rad immer neu erfinden muss, wenn's schon wunderbar rund läuft.



Ich will das Rad nicht neu erfinden, sondern hatte bis vor kurzen keine Ahnung von dieser fp Unit, da ich den Code zuvor schon seit 1999 damals noch unter OS/2's Speedsoft Sibyl und zuvor noch Dlephi einsetzte - ntürlich war das alles 32bit , und da gabs es noch kein fpc, und da dieser Code auch auf 64bit CPU's unter fp herrvorgang funktioniert (bis auf das 2GB Problem) hatte ich keinen Anlass mich nach etwas andern umzuschauen erst als ich nicht mehr weiter wusste , enteckte ich die md5 unit von fp die auch unter 64bit korrekt funktioniert - warum und wieso hab ich keine Ahnung.


Wenn Reinhards Quellcode hier noch aus Delphi 4 Zeiten stammt, sind wohl eher die fpc Funktionen das neu erfundene Rad

Haarspalterei. Wenn es funktionierende Standards gibt, sollte man sie verwenden. Und da macht es keinen Sinn, alten Code aus der Versenkung zu holen. Er hat damit Probleme, die lange gelöst wurden. Wenn man so programmiert, kann man es auch sein lassen. Schließlich muss man dann noch Fehler ausmerzen, die lange von anderen gelöst wurden. Lidtragende sind dann die Endbenutzer. Und die eigenen Probleme auf Endbenutzer abzuwälzen in FOrm von unzuverlässiger oder schlecht bedienbarere Software ist Kindergarten. Da kann man es auch sein lassen.

So ist es , der Code funktionierte bisher hervorragend , da ich selber kein 64bit OS einsetzte ist mir der Fehler bisher auch nicht ins aufgefallen.

Hätte der Thread-Ersteller hier ein Doppel-Posting gemacht, hätte man ihn verschrieen. Da sein Anliegen ein lange gelöstes Problem ist, liegt hier implizit ein redundanter Post vor. Und warum hat ihn niemand auf die Stadard-Funktionen hingewiesen? Das hätte ihm einen Haufen Zeit gespart.


Wurde bereits hingewiesen ...

Trotzdem danke für den Hinweis.

Werde halt dann den fp code nehmen und ein wenig verändern müssen weil der bestehende code unter Windows keine Dateien mit umlauten öffnen kann (was aber wieder ein fp problem ist, das die lauarus entw mit der UTF8 Unit umgehen)

Trotzdem bin ich nicht der Meinung man sollte auf Vorgefertigte Units zurückgreifen.

Einmal Schreiben , überall laufen lassen funktioniert hier halt nur mit 32bit, trotzdem sollte es auch mit 64bit funken, die fp units sind ja kein fix (weil nicht gleich) sondern eher ein workaround.

Aber egal will ja hier keine Politik Diskusion vom Zaun brechen ...

Verwende ich halt den fp code und die Sache hat sich damit hoffentlich Erledigt.

Reinhard
Beiträge: 46
Registriert: Fr 26. Sep 2008, 16:56

Re: Probleme mit code unter 64bit cpu

Beitrag von Reinhard »

ruewa hat geschrieben:Sei doch nicht so ungnädig, Antrepolit! Selbstverständlich kann man alten Code weiterverwenden, wenn er sich bewährt hat. Soweit ich Reinhard verstanden habe, wollte er schlicht und einfach ein funktionierendes Programm auf einem 64-Bit-Rechner installieren und hat dabei erstmal keine Probleme erwartet (hätte ich auch nicht. denn das ist ja gerade das Konzept von Write Once, Compile Anywhere). Hinterher ist man natürlich immer schlauer.

Jetzt gibt es allerdings ein recht mysteriöses Problem. Warum sollte ein 64-Bit-Rechner mit den vorhandenen Integer-Typen (nach außen!) anders umgehen als eine 32-Bit-Kiste? Ob es an den Datentypen liegt oder an sonstwas, jedenfalls ist die Möglichkeit nicht von der Hand zu weisen, daß Reinhard hier auf einen fpc-Bug gestoßen ist. Dem lohnt es sich schon nachzugehen!

Edit: Weil mir das Argument nicht einleuchtet:

theo hat geschrieben:... du musst wahrscheinlich int64 bzw. QWord verwenden, statt Cardinal etc.

Daß 64-Bit-Integers für eine 64-bit-CPU geeignete Typen sind, ist klar. Aber sind sie auch geeigneter? Für bestimmte Anwendungen sicherlich, aber generell? Warum sollte ein 64-Bit-System nicht in der Lage sein, mit den in der 32-Bit-Welt etablierten Datentypen genauso umzugehen wie eine 32-Bit-Architektur?

Noch weiter gefragt: Die 2-GB-Schallmauer ist ja die Bereichsgrenze der (vorzeichenbehafteten) 32-Bit-Ganzzahl. Was macht FPC auf einer 64-Bit-Maschine in dem Moment, wo in einem 32-Bit-Register ein Überlauf stattfinden würde? Das 64-Bit-Register lacht noch nicht mal darüber und zählt einfach weiter. Generiert FPC einen Code, der dies simuliert / überprüft? Wäre das dann der Fall, wenn man mit Bereichs- und/oder Überlaufs-Überprüfung kompiliert (Projekt/Projekteinstellungen/Debuggen bzw. -Cr/-Co)?

@Reinhard: In diese Richtung würde ich ehestens vermuten, allerdings konnte ich im Quelltext erstmal keinen Kandidaten für einen solchen Effekt ausmachen. Hast Du das Programm mal mit diesen Bereichs-/Überlaufsüberprüfungen kompiliert?

Gruß Rüdiger


Habe ich schon probiert, aber mit range check enabled will das werkel überhaupt nicht funken, da kommt gleich nach dem ersten "read" ein rangecheck error in "function ff".

Egal, muss ich halt den fp code nehmen trotzdem danke für den Hinweis

Antworten