![]() |
JCL Stack Exception unter Firemonkey in Win64/32
Liste der Anhänge anzeigen (Anzahl: 1)
Hat schon jemand JclLastExceptStackListToStrings von JclDebug in einer Windows Firemonkey Applikation zur Call-Stack-Ausgabe nach einer Exception eingesetzt?
Ich versuche unter Delphi 10.2 in einer Firemonkey Applikation dieses Teil das erste mal auch unter Firemonkey einzubauen und bekomme dabei unter Win64 wie auch unter Win32 ein unterschiedlichen und irreführenden Stacks mit Einträgen die ich mir nicht erklären kann. Meine Test-Applikation löst auf tastenklick eine Exception aus und ist ganz einfach:
Delphi-Quellcode:
Im Anhang zeige ich die unterschiedlichen Ausgabe der Release-Konfiguration für Win32/Win64 Plattformen. uses JclDebug; procedure TForm2.FormCreate(Sender: TObject); begin Application.OnException := ExceptionHandler; end; procedure TForm2.ExceptionHandler(Sender: TObject; E: Exception); begin ListBox1.Clear; ListBox1.Items.Add('Exception Class : ' + E.ClassName); ListBox1.Items.Add('Exception Message: ' + E.Message); JclLastExceptStackListToStrings(ListBox1.Items); end; procedure TForm2.Button1Click(Sender: TObject); procedure DivByZeroTest(zero: integer); begin Caption := IntTostr(3 div zero); end; var n: TForm; begin n := pointer(1); case ComboBox1.ItemIndex of 0: DivByZeroTest(ComboBox1.ItemIndex); 1: n.Free; 2: n.Show; end; end; initialization Include(JclStackTrackingOptions, stRawMode); JclStartExceptionTracking; finalization JclStopExceptionTracking; end. In der Debug-Konfiguration sehe ich nur kleine Abweichungen zum Release-Stack, wobei vermutlich die Compiler Optimierung die Differenz erklären kann. Hat jemand eine Idee an was es liegen könnte oder funktioniert JCLDebug under FMX grundsätzlich nicht? Setzt jemand bereits erfolgreich eine Käufliche Kompetente unter Firemonkey ein? Gibt es eine Lösung die auf allen Plattformen läuft? (MacOS, iOS, Android?) |
AW: JCL Stack Exception unter Firemonkey in Win64/32
Sieht bei mir unter 10 Seattle ähnlich aus. Als "funktioniert nicht" würde ich es jetzt nicht abstempeln, es ist ja nur zusätzlicher Müll drin - Das Wichtige (Button1Click, gefolgt von DivByZeroTest) ist ja drin 🤷
Für MacOS kenne ich nichts, für iOS und Android habe ich mal gesehen dass diese Zauberer mal etwas gebastelt hatten: |
AW: JCL Stack Exception unter Firemonkey in Win64/32
@Günther: Ja, es stimmt, einen Hinweis auf den Fehler kann man mit dieser Lösung auf jeden Fall bekommen. Nur bei der Fehlersuche nach sporadischen Race-Conditions ist es schon schwierig genug, denn Fehler zu finden. Einen auch nur teilweise falschen Stack kann einen aber auch auf eine falsche Fährte locken und es gibt einem jedenfalls nicht ein besseres Vertrauen. :oops:
Wieso Embarcadero nicht bereits einen brauchbaren Call-Stack in der RTL für alle Exceptions implementiert hat, ist mir schon ein kleines Rätsel. Ich bin sicher nicht der einzige der sowas vermisst. |
AW: JCL Stack Exception unter Firemonkey in Win64/32
Nach einiges Recherche und analysieren des JCLDebug Codes habe ich eine Lösung gefunden, die mal das tut, was ich erwartete.
Ich habe dabei den TJclStackInfoList.IgnoreLevels ![]() abhängig vom Compiler erhöht. Wieso jetzt für den IgnoreLevel eine 10 für Windows 64 und eine 32 für Windows 32 eingesetzt wird, konnte ich leider nur experimentell ermitteln und kenne die Details dazu nicht. Ich vermute, dass bei FMX der Exception-Handler etwas anders gelöst ist als bei der VCL und dieser IgnoreLevel hilft, jenen Stack-Teil des etwas grösseren FMX-Exception-Handlers zu verstecken. Mit folgendem Code überschreibe ich die Standard-Lösung von JCLDebug. Vielleicht hilft es ja auch anderen weiter:
Delphi-Quellcode:
Danach muss man nur noch in der Application.OnException methode den E.StackTrace auswerten.
function GetExceptionStackInfoProc(P: System.PExceptionRecord): Pointer;
var LLines: TStringList; LText: String; LResult: PChar; jcl_sil: TJclStackInfoList; begin LLines := TStringList.Create; try {$IFDEF WIN64} jcl_sil := TJclStackInfoList.Create(true, 10, p.ExceptionAddress, false, nil, nil); {$ENDIF} {$IFDEF WIN32} jcl_sil := TJclStackInfoList.Create(true, 32, p.ExceptionAddress, false, nil, nil); {$ENDIF} try jcl_sil.AddToStrings(LLines); finally FreeAndNil(jcl_sil); end; LText := LLines.Text; LResult := StrAlloc(Length(LText)); StrCopy(LResult, PChar(LText)); Result := LResult; finally LLines.Free; end; end; function GetStackInfoStringProc(Info: Pointer): string; begin Result := string(PChar(Info)); end; procedure CleanUpStackInfoProc(Info: Pointer); begin StrDispose(PChar(Info)); end; initialization if JclStartExceptionTracking then begin Exception.GetExceptionStackInfoProc := GetExceptionStackInfoProc; Exception.GetStackInfoStringProc := GetStackInfoStringProc; Exception.CleanUpStackInfoProc := CleanUpStackInfoProc; end; finalization if JclExceptionTrackingActive then begin Exception.GetExceptionStackInfoProc := nil; Exception.GetStackInfoStringProc := nil; Exception.CleanUpStackInfoProc := nil; JclStopExceptionTracking; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:46 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