AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung JCL Stack Exception unter Firemonkey in Win64/32
Thema durchsuchen
Ansicht
Themen-Optionen

JCL Stack Exception unter Firemonkey in Win64/32

Ein Thema von Christoph Schneider · begonnen am 7. Jan 2019 · letzter Beitrag vom 8. Jan 2019
Antwort Antwort
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#1

JCL Stack Exception unter Firemonkey in Win64/32

  Alt 7. Jan 2019, 15:21
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:

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.
Im Anhang zeige ich die unterschiedlichen Ausgabe der Release-Konfiguration für Win32/Win64 Plattformen.
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?)
Miniaturansicht angehängter Grafiken
jclstackexception.jpg  
Christoph Schneider
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: JCL Stack Exception unter Firemonkey in Win64/32

  Alt 8. Jan 2019, 07:51
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:
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: JCL Stack Exception unter Firemonkey in Win64/32

  Alt 8. Jan 2019, 10:24
@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.

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.
Christoph Schneider
  Mit Zitat antworten Zitat
Benutzerbild von Christoph Schneider
Christoph Schneider

Registriert seit: 7. Okt 2008
Ort: CH-Baar
54 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: JCL Stack Exception unter Firemonkey in Win64/32

  Alt 8. Jan 2019, 16:47
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 http://wiki.delphi-jedi.org/JCL_Help...t.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:
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.
Danach muss man nur noch in der Application.OnException methode den E.StackTrace auswerten.
Christoph Schneider

Geändert von Christoph Schneider ( 8. Jan 2019 um 16:59 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:42 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