Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Stacktrace - Unterschied bei "raise" oder "access violation" (https://www.delphipraxis.net/198413-stacktrace-unterschied-bei-raise-oder-access-violation.html)

Ralf Kaiser 31. Okt 2018 06:37


Stacktrace - Unterschied bei "raise" oder "access violation"
 
Halli Hallo,

In einem Programm wird mittels JCLDebug der Stacktrace aufgzeichnet wenn eine Exception auftritt. Eine gültige MAP-Datei ist vorhanden (in der Releaseversion integriert in das Programm). Die Stacktraces sind korrekt und listen die Fehlerstelle auf wie sie sollen. Die erzeugten Stacktraces haben auch jeweils eine ganze Reihe von Einträgen, so dass man schön sehen kann was das Programm bis zum Fehler ausgeführt hat.

Bein "normalen" Exceptions klappt das hervorragend. Mit "normal" meine ich Exceptions die im Quelltext mittels "raise" ausgelöst werden.

Wenn ich so etwas mache löst das natürlich eine Access violation aus (nur zum Test):

Delphi-Quellcode:
lTestObject := nil;
lTestObject.AddObject('Test', Self);
Das seltsame ist aber, dass in diesem Fall der Stacktrace nur aus genau einer Zeile besteht.

Ich hab dann mal ausprobiert die selbe Exception (Access violation) so auszulösen:

Delphi-Quellcode:
// jetzt mal manuell...
raise EAccessViolation.Create('Access violation manuell ausgelöst.');
In diesem Fall erhalte ich wieder einen korrekten Stacktrace, also einen mit einer Reihe von Einträgen an denen man den bisherigen Ausführungspfad bis zur Exception nachvollziehen kann.

Kann mir jemand den Unterschied zwischen einer geraiseten Excption und einer die durch einen echten Fehler entstand erklären?

Vielen Dank schon mal,
Ralf

KodeZwerg 31. Okt 2018 07:57

AW: Stacktrace - Unterschied bei "raise" oder "access violation"
 
Frage: Wie schaut dein Demo #1 aus wenn Du selbiges in ein try..finally/except block ausführst?

Ralf Kaiser 31. Okt 2018 08:25

AW: Stacktrace - Unterschied bei "raise" oder "access violation"
 
Zitat:

Zitat von KodeZwerg (Beitrag 1417147)
Frage: Wie schaut dein Demo #1 aus wenn Du selbiges in ein try..finally/except block ausführst?

Hatte ich noch nicht ausprobiert, was ich jetzt nachgeholt habe aber es ändert sich nichts.

Aufgefallen ist das Problem ja auch bei Exceptions die wegen echten Programmfehlern aufgetreten waren (irgendwo war mal ein Pointer unerwartet NIL und da hat es geknallt, der Stacktrace sagte dann, weil nur eine Zeile, nichts aus)

KodeZwerg 31. Okt 2018 09:23

AW: Stacktrace - Unterschied bei "raise" oder "access violation"
 
Oh, Danke für das Prüfen, ich hatte gehofft das so der Errorhandler mehr wiedergibt.
Heut Abend teste ich das auch mal, kann gerade nicht.

Ralf Kaiser 31. Okt 2018 09:24

AW: Stacktrace - Unterschied bei "raise" oder "access violation"
 
Mittlerweile habe ich herausgefunden, dass diese extrem kurzen Stacktraces (1 Zeile) scheinbar erzeugt wurden weil in den Optionen (TJclStackTrackingOptions) die Option
Delphi-Quellcode:
[stRawMode]
fehlte.

Trotzdem unterscheiden sich die Stacktraces immer noch. Der Trace der eine Exception die geraiset wird enthält ist kürzer in dem anderen ist scheinbar noch der Code für die Erstellung der Exception selbst enthalten, womit er länger ist (Aufrufe von System.GetMem usw.)

Der schöne Günther 31. Okt 2018 17:11

AW: Stacktrace - Unterschied bei "raise" oder "access violation"
 
Kannst du ein kleines Testprojekt einstellen? Wenn ich ein Test-VCL-Projekt das folgendermaßen aussieht:

Delphi-Quellcode:
implementation

uses JclDebug;

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
begin
   Application.OnException := handleException;
end;

procedure TMainForm.Button1Click(Sender: TObject);
var
   lTestObject: TStringList;
begin
   lTestObject := nil;
   lTestObject.AddObject('Test', Self);
end;

procedure TMainForm.handleException(Sender: TObject; E: Exception);
begin
   if Assigned(e) then
      Memo1.Lines.Text := e.StackTrace;
end;
liefert folgenden Stack:

Code:
(001F7D0C){StackTestProject.exe} [005F8D0C] GUI.MainForm.TMainForm.Button1Click + $C
(00007A9B){StackTestProject.exe} [00408A9B] System.@HandleAnyException + $33
(0011D989){StackTestProject.exe} [0051E989] Vcl.Controls.TWinControl.WndProc + $5E9
(00131CE8){StackTestProject.exe} [00532CE8] Vcl.StdCtrls.TButtonControl.WndProc + $6C
(0011DAEF){StackTestProject.exe} [0051EAEF] Vcl.Controls.DoControlMsg + $23
(0011D989){StackTestProject.exe} [0051E989] Vcl.Controls.TWinControl.WndProc + $5E9
(0011CFA8){StackTestProject.exe} [0051DFA8] Vcl.Controls.TWinControl.MainWndProc + $2C
(000BFBF8){StackTestProject.exe} [004C0BF8] System.Classes.StdWndProc + $14
(0011DA9A){StackTestProject.exe} [0051EA9A] Vcl.Controls.TWinControl.DefaultHandler + $E6
(0011D989){StackTestProject.exe} [0051E989] Vcl.Controls.TWinControl.WndProc + $5E9
(00131CE8){StackTestProject.exe} [00532CE8] Vcl.StdCtrls.TButtonControl.WndProc + $6C
(000BFBF8){StackTestProject.exe} [004C0BF8] System.Classes.StdWndProc + $14
Interessant wären hierbei wahrscheinlich insbesondere die dproj-Datei deines Testprojekts...

Ralf Kaiser 31. Okt 2018 18:04

AW: Stacktrace - Unterschied bei "raise" oder "access violation"
 
Heute nicht mehr (und Morgen ist Feiertag). Ich kann am Freitag mal die unterscheidlichen Stacktraces erzeugen. Wobei das Hauptproblem (der einzeilige Stacktrace) ja durch die Angabe der Raw-Option gelöst ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:04 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