Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi AV verursacht durch Code Optimierung (https://www.delphipraxis.net/125630-av-verursacht-durch-code-optimierung.html)

Boombuler 9. Dez 2008 11:07


AV verursacht durch Code Optimierung
 
Hi,

heute ist uns hier was aufgefallen was die Delphi Code Optimierung verursacht. Durch fehlerhaftes Optimieren der lokalen Variablen wird eine Zugriffsverletzung verursacht. Ich habe den Original-Code mal auf ein sinnloses Beispiel übertragen. Vielleicht kann mir ja jemand von euch sagen wie ich das am besten umgehen kann. Da der Code der original Anwendung über 1,5 Mio. Zeilen Code hat würde ich die Code Optimierung gerne eingeschaltet lassen und auch nicht umbedingt alle Aborts suchen ob der Fehler dort auftreten kann.


Beispiel (getestet mit D2005 und D2009)
Delphi-Quellcode:
procedure ShowSum(a,b,c,d,e,g,f: Integer);
var sum: Integer;
begin
  sum := a+b+c+d+e+f+g;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  x: Integer;
  a, b,c: Integer;
begin
  b := 2;
  if (GetTickCount mod 2) = 0 then
  begin
    a := GetTickCount;
    b := a div 2;
    x := 4915; // Exception @ 1337
    c := Handle;
  end
  else
  begin
    a := Handle;
    b := a div 2;
    x := 53259; // Exception @ D00F
    c := GetTickCount;
  end;
  ShowSum(a,b,c,5,4,x,9);
  Abort;
end;
Der Fehler wird dadurch ausgelöst, dass die Variable X per Optimierung auf EBP gelegt wird, welches von Abort zur Berechnung der Aufruf-Adresse verwendet wird.

PS: GetTickCount und Handle wurden hier nur verwendet, damit Delphi einige stellen nicht komplett optimiert!

MfG
Boombuler

Boombuler 9. Dez 2008 11:51

Re: AV verursacht durch Code Optimierung
 
Nep wie ich mittlerweile rausgefunden habe ein bekanntes Problem:
http://qc.codegear.com/wc/qcmain.aspx?d=54331

MfG
Boombuler

DMW 9. Dez 2008 12:30

Re: AV verursacht durch Code Optimierung
 
Das ist kein Codegenerierungsfehler, sondern ReturnAddr verläßt sich darauf, daß Abort einen Stackframe generiert, was in optimiertem Code nicht der Fall ist.

Die beste Alternative wäre vermutlich, wenn ReturnAddr anstelle von EBP auf ESP zugriffe:
Delphi-Quellcode:
procedure Abort;

  function ReturnAddr: Pointer;
  asm
          MOV    EAX,[ESP + 4]
  end;

begin
  raise EAbort.CreateRes(@SOperationAborted) at ReturnAddr;
end;

Boombuler 9. Dez 2008 12:43

Re: AV verursacht durch Code Optimierung
 
Thx, scheint zu funktionierenn ;)


Zitat:

Zitat von SubData
Geh wieder spielen ;-)

Jap mach ich jetzt auch!

himitsu 9. Dez 2008 17:30

Re: AV verursacht durch Code Optimierung
 
Im Notfall kann man die CodeOptimierung auch teilweise abschalten (allerdings nicht für einzelne Codezeilen, sondern nur für ganze Funktionen, Prozeduren oder für ganze Units bzw. Programme)
Delphi-Quellcode:
procedure ShowSum(a,b,c,d,e,g,f: Integer);
var sum: Integer;
begin
  sum := a+b+c+d+e+f+g;
end;

{$O-}

procedure TForm1.Button1Click(Sender: TObject);
var
  x: Integer;
  a, b,c: Integer;
begin
  ...
end;

{$O+}
die Optimierung muß doch in der aufrufenden Funktion/Prozedur deaktiviert werden, oder doch in der aufgerufenen (also Abort) :gruebel:

DMW 11. Dez 2008 07:32

Re: AV verursacht durch Code Optimierung
 
Zitat:

Zitat von himitsu
die Optimierung muß doch in der aufrufenden Funktion/Prozedur deaktiviert werden, oder doch in der aufgerufenen (also Abort) :gruebel:

Weder noch. Das Problem ist mit großer Sicherheit ein Bug in Abort; den Zusammenhang mit der Optimierung erachte ich als eher zufällig. Ich halte es nicht für ausgeschlossen, daß man den Compiler auch mit deaktivierter Optimierung dazu bringen kann, das EBP-Register zu recyclen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:31 Uhr.

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