Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Access Violations nach Update auf XE3 (https://www.delphipraxis.net/170884-access-violations-nach-update-auf-xe3.html)

Nersgatt 8. Okt 2012 15:10

Access Violations nach Update auf XE3
 
Hallo!

Wir haben unsere Anwendung von Delphi 2010 auf XE 3 umgestellt. Seit dem haben wir an scheinbar zufδlligen Stellen im Programm Access Violations. Ich kann mir da nicht den geringsten Reim drauf machen. Ich habe die Vermutung, dass die Fehler nur in Formularen auftreten, die ein TClientDataSet beinhalten. Aber das ist Spekulation.

Ich hab nun FastMM mit dem FullDebugMode installiert. Allerdings kann ich mit der Ausgabe so gar nichts anfangen. Kann mir vielleicht jemand auf die Sprόnge helfen?
Das sieht dann z.B. so aus:
Zitat:

---------------------------
sofhie.exe: Memory Error Detected
---------------------------
FastMM has detected an error during a FreeMem operation. The block footer has been corrupted.



The block size is: 39



This block was allocated by thread 0x960, and the stack trace (return addresses) at the time was:

4069D1

40DDF9

40DF2A

6E54FD [Data.DB][Data][Data.DB.TStringField.GetValue]

6E53D7 [Data.DB][Data][Data.DB.TStringField.GetAsVariant]

AB6BAD [cxDB.pas][cxDB][cxDB.GetFieldValue][395]

AC1118 [cxDBData.pas][cxDBData][cxDBData.TcxValueDefDBReader.GetValue][3398]

90F02E [cxDataStorage.pas][cxDataStorage][cxDataStorage.TcxDataStorage.ReadRecord][2340]

97FBCE [cxCustomData.pas][cxCustomData][cxCustomData.LoadData][8627]

97FD52 [cxCustomData.pas][cxCustomData][cxCustomData.TcxCustomDataController.LoadStorage][8666]

AC4895 [cxDBData.pas][cxDBData][cxDBData.TcxDBDataController.LoadStorage][5164]



The block is currently used for an object of class: Unknown



The allocation number is: 2091660



The block was previously freed by thread 0x960, and the stack trace (return addresses) at the time was:

40697E

40B6B5

6E0D2C [Data.DB][Data][Data.DB.TNamedItem.HashName]

41A4B0 [FastMM4.pas][FastMM4][FastMM4.DebugFreeMem][8893]

41A4C5 [FastMM4.pas][FastMM4][FastMM4.DebugFreeMem][8900]

40697E

40B6B5

6E0D2C [Data.DB][Data][Data.DB.TNamedItem.HashName]

7738A1AD [Unknown function at EtwSetMark]

77356500 [Unknown function at _wcsnicmp]

41A4B0 [FastMM4.pas][FastMM4][FastMM4.DebugFreeMem][8893]



The current thread ID is 0x960, and the stack trace (return addresses) leading to this error is:

40697E

40E07E

6E55E9 [Data.DB][Data][Data.DB.TStringField.GetValue]

6E53D7 [Data.DB][Data][Data.DB.TStringField.GetAsVariant]

AB6BAD [cxDB.pas][cxDB][cxDB.GetFieldValue][395]

AC1118 [cxDBData.pas][cxDBData][cxDBData.TcxValueDefDBReader.GetValue][3398]

90F02E [cxDataStorage.pas][cxDataStorage][cxDataStorage.TcxDataStorage.ReadRecord][2340]

97FBCE [cxCustomData.pas][cxCustomData][cxCustomData.LoadData][8627]

97FD52 [cxCustomData.pas][cxCustomData][cxCustomData.TcxCustomDataController.LoadStorage][8666]

AC4895 [cxDBData.pas][cxDBData][cxDBData.TcxDBDataController.LoadStorage][5164]

98027E [cxCustomData.pas][cxCustomData][cxCustomData.TcxCustomDataController.UpdateStorage][8870]



Current memory dump of 256 bytes starting at pointer address 7D6A63B0:

00 00 00 00 1F 00 00 00 68 00 00 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80

80 80 80 80 80 80 80 80 80 80 80 80 87 CD F1 77 80 80 80 80 80 80 80 80 00 00 00 00 F1 63 6A 7D

. . . . . . . . h . . . € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € € € € € € € € € € € € € € € € € € € € €

€ € € € € € € € € € € € ‡ Ν ρ w € € € € € € € € . . . . ρ c j }


---------------------------
OK
---------------------------
Danke!
Jens

jbg 8. Okt 2012 16:56

AW: Access Violations nach Update auf XE3
 
TDataSet.GetData ist seit XE3 fehlerhaft. (http://qc.embarcadero.com/wc/qcmain.aspx?d=109219)


Dazu kann ich eigentlich nur Uwe Schuster zitiere:
Zitat:

where dev didn't understood code. Guess QC109219

Nersgatt 9. Okt 2012 07:33

AW: Access Violations nach Update auf XE3
 
Vielen Dank fόr den Hinweis. Leider scheint es das nicht zu sein. Ich hab die Datei bei mir gepatcht und die gepatchte Datei direkt meinem Projekt hinzugefόgt.
Er kommt nie in den Zweig, wo FValidating True ist. Hδtte mich auch gewundet, weil wir an der Stelle keinen Ereignishandler fόr Validating haben.

Hat jemand noch eine Idee? Ich schaffe es ja nicht mal, per Debugger direkt an die Stelle zu springen, wo der Fehler auftritt.
Das Letzte, wo ich fehlerfrei durchsteppen kann ist Data.DB.TStringField.GetValue. Das geht ganz oft gut, bis es dann irgendwann nach dem END von dieser Fuction knallt.

Bummi 9. Okt 2012 07:53

AW: Access Violations nach Update auf XE3
 
Imho kracht ein Zugriff auf ein nicht gepostetes NULL Feld.

Nersgatt 9. Okt 2012 10:50

AW: Access Violations nach Update auf XE3
 
Liste der Anhδnge anzeigen (Anzahl: 1)
Ne, das mit dem Nullfeld ist es wohl auch nicht.

Ich hab es jetzt mal auf ein minimales Beispielprojekt runtergebrochen.
Ihr findest das Projekt im Anhang.
Sobald ich das Grid aus dem Formular entferne, funktioniert es όbrigens.

Hόlfδ! :(

Nersgatt 10. Okt 2012 12:41

AW: Access Violations nach Update auf XE3
 
So, das Problem ist umzingelt.
Das Problem tritt beim TStringField innerhalb des TClientDataSet auf. Aber nur in dem Fall, wenn TStringField.Size kleiner ist, als das Feld in der Datenbank.
Beispiel: ich habe in der Datenbank ein Feld VarChar(30) und das TStringField, worein die Daten solle hat nur die Size von 20. Dann kracht es.

Nun ist die Frage: ist das ein Fehler in der DB.Data.pas, oder sind wir selbst schuld? Delphi 2010 hatte das noch problemlos geschluckt, wenn das Feld zu klein ist.

Rolf Frei 10. Okt 2012 18:19

AW: Access Violations nach Update auf XE3
 
Ich kann das selber auch reproduzieren. Das ist zu 100% nicht dein Fehler. Ist leider ein weiterer sehr όbler Bug und betrifft nicht das TClientDataset, sondern jedes von TDataset abgeleitete Objekt. Mein Test benutzt eine 3rd Party Komponente und auch damit kann ich es reproduzieren.

Bitte melde das mit einem Beispiel in QC.

[EDIT]
Bin nicht sicher ob das όberhaupt was mit dem TDataset zu tun hat oder ob es am TDBGrid liegt. Der AV tritt in TDBGridInplaceEdit.UpdateContents bei der Zeile:
Font.Assign(Column.Font);

Wenn ich da aber schrittweise debugge, kann ich nicht sehen was da falsch sein soll. Bin daher όberhaupt nicht sicher was zu diesem Fehler fόhrt.

[EDIT2]
Habe nun mal das DB Grid entfernt und ein normales TDBEdit angehδngt. Auch damit knallt es. Manchmal erst beim Beenden der Applikation. Wird also doch irgendwie mit TField.Size zusammen hδngen.

Rolf Frei 15. Okt 2012 14:41

AW: Access Violations nach Update auf XE3
 
Habe mir das nun mal genauer angeschaut und habe das Problem gefunden. Da wird in TStringField.GetValue zu wenig Buffer alloziert, wenn Size kleiner ist als das effektive DB Feld. Habe folgenden Fix gemacht und nun scheint alles bestens zu laufen. Damit sollten deine AV's Geschichte sein. Habe όbrigens einen QC-Eintrag mit meinem FIX erstellt.

Einen gleichartigen Fix sollte man auch noch bei TWideStringField.GetValue machen.)

FIX fόr TStringField.GetValue:
Delphi-Quellcode:
function TStringField.GetValue(var Value: AnsiString): Boolean;
var
  Buffer: TValueBuffer;
  NullIndex: Integer;
  Str: string;
begin
  // orig. XE3
  // SetLength(Buffer, DataSize);

  // === Fix as in older Delphi Versions ===
  if DataSize > dsMaxStringSize + 1 then
    SetLength(Buffer, DataSize)
  else
    SetLength(Buffer, dsMaxStringSize + 1);
  // === End of Fix ===

  Result := GetData(Buffer);
  if Result then
  begin
    if Transliterate and (Buffer <> nil) and (Buffer[0] <> 0) then
      DataSet.Translate(PAnsiChar(@Buffer[0]), PAnsiChar(@Buffer[0]), False);
    Str := TEncoding.ANSI.GetString(Buffer);
    NullIndex := Str.IndexOf(#0);
    if NullIndex >= 0 then
      Value := AnsiString(Str.Remove(NullIndex))
    else
      Value := AnsiString(Str);
  end;
end;
Und hier fόr TWideStringField:
Delphi-Quellcode:
function TWideStringField.GetValue(var Value: string): Boolean;
var
  Buffer: TValueBuffer;
  NullIndex: Integer;
  Str: string;
begin
  // orig. XE3
  // SetLength(Buffer, ((DataSize div 2) + 1) * SizeOf(Char));

  // rf
  // === Fix as in older Delphi Versions ===
  if DataSize > ((dsMaxStringSize div 2) + 1) * SizeOf(Char) then
    SetLength(Buffer, ((DataSize div 2) + 1) * SizeOf(Char))
  else
    SetLength(Buffer, ((dsMaxStringSize div 2) + 1) * SizeOf(Char));
  // === End of Fix ===

  Result := GetData(Buffer, False);
  if Result then
  begin
    Str := TEncoding.Unicode.GetString(Buffer);
    NullIndex := Str.IndexOf(#0);
    if NullIndex >= 0 then
      Value := Str.Remove(NullIndex)
    else
      Value := Str;
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz