JCL Exception Dialog



  • Hallo zusammen

    Ich setze nun seit geraumer Zeit den JCL (Jedi) Exception Dialog ein um ein Stack Trace usw bei einer Exception bzw AV zu erhalten.
    Nun kam mir die Idee den Exceptionhandler noch etwas auszubauen (LogFiles, ...) und dann in eine DLL zu verlagern.
    Die DLL sollte dynamisch gelinkt werden, damit spätere Erweiterungen auch in ältere Programme durch Austausch der DLL mit einfließen können.

    Nun habe ich das Problem, daß der Exceptionhandler nicht aufgerufen wird. DLL wird momentan noch statisch gelinkt (erscheint mir vorerst einfacher).

    Die DLL ruft über initialization den folgenden Code auf.

    var
      AppEvents: TApplicationEvents = nil;
    
    procedure InitializeHandler;
    begin
      if AppEvents = nil then
      begin
        AppEvents := TApplicationEvents.Create(nil);
        AppEvents.OnException := TExceptionDialog.ExceptionHandler;
    
        RemoveIgnoredException(EAbort);
        JclStackTrackingOptions := JclStackTrackingOptions + [stTraceAllExceptions];
        JclStackTrackingOptions := JclStackTrackingOptions + [stRawMode];
        JclStackTrackingOptions := JclStackTrackingOptions + [stStaticModuleList];
        JclStackTrackingOptions := JclStackTrackingOptions + [stDelayedTrace];
        JclDebugThreadList.OnSyncException := TExceptionDialog.ExceptionThreadHandler;
        JclHookThreads;
        JclStartExceptionTracking;
    
        if HookTApplicationHandleException then
          JclTrackExceptionsFromLibraries;
      end;
    end;
    

    Hiermit wird dem OnException Event der Handler zugewiesen. Dieser Code wird auch ausgeführt.
    Allerdings wird bei einer Exception der Dialog nicht angezeigt.
    Gibt es verscheidene OnException handler, in der DLL und EXE?

    MfG Stephan



  • Stephan schrieb:

    Gibt es verscheidene OnException handler, in der DLL und EXE?

    Wenn du nicht mit Laufzeit-Packages linkst, dann schon. Du solltest zumindest rtl*.bpl und vcl*.bpl dynamisch linken.



  • Hallo zusammen

    @audacia
    Danke für die Info hat soweit funktioniert (habe vcl und rtl als Laufzeit Package zugelassen).

    Wie macht ihr das normalwerweise, alles mit in die exe packen oder extra files mitgeben?
    Gibt es hier Vor- bzw Nachteile, außer das zusätzliche Files mitgegeben werden müssen?

    Vielen dank im voraus.
    MfG Stephan



  • Stephan schrieb:

    Wie macht ihr das normalwerweise, alles mit in die exe packen oder extra files mitgeben?

    Kommt darauf an. Größere, modulare Anwendungen sind manchmal besser zu handhaben, wenn sie aus separaten Packages bestehen, ansonsten aber ist eine abhängigkeitsfreie Executable natürlich einfacher.

    Stephan schrieb:

    Gibt es hier Vor- bzw Nachteile, außer das zusätzliche Files mitgegeben werden müssen?

    Eher Vorteile: wenn du DLLs benutzt, muß der gesamte VCL- und RTL-Code nur einmal in den Arbeitsspeicher geladen werden. Nachteil ist das Deployment - aber nur die zwei zusätzlichen Dateien im Programmordner sollten niemanden stören.



  • Hallo zusammen

    Jetzt hab ich doch noch ein Frage.
    Die DLL mit dem ganzen Exception Dialog usw. funktioniert wenn ich vcl und rtl als Laufzeitpackage zulasse.
    Meine DLL ist mit BCB2009 gebaut.
    Nun wollte ich die DLL gerne auch in einem alten BCB6 Projekt verwenden.

    Ist es richtig, daß der Dialog nicht aufgerufen wird, da die vcl und rtl Laufzeitpackages unterschiedlich sind?
    Gibt es hier noch andere Möglichkeiten dies ans Laufen zu bringen?

    MfG Stephan



  • Stephan schrieb:

    Nun wollte ich die DLL gerne auch in einem alten BCB6 Projekt verwenden.

    Dann mußt du auch ein separates Build mit dem C++Builder 6 erstellen.

    Für die gleichzeitige Verwendung von Modulen, die mit verschiedenen Compilerversionen erstellt wurden, gilt das gleiche wie für verschiedene Compiler: du mußt dich mehr oder weniger auf ein C-Interface beschränken.

    In der Praxis ist es nicht ganz so schlimm, aber das folgende darf etwa beim C++Builder nicht über Compilerversionsgrenzen hinaus ausgetauscht werden:
    - STL-Klassen (C++Builder 6 verwendet STLPort, spätere Versionen verwenden unterschiedliche Revisionen der Dinkumware-Bibliothek)
    - Delphi-Klassen (es gibt signifikante Unterschiede zwischen den RTLs mehrerer Versionen, so daß du dich nicht wundern brauchst, wenn du beim Austausch von Delphi-Objekten öfter mal eine nicht nachvollziehbare Zugriffsverletzung erhältst)
    - Delphi-Exceptions (aus demselben Grunde; C++-Exceptions sind auch nicht problemlos, aber da es in der C++-RTL keine nennenswerten strukturellen Änderungen gab, dürften sie funktionieren).

    Es ist zwar möglich, verschiedene Versionen von RTL und VCL in einem einzigen Prozeß zu verwenden, allerdings habe ich keine Ahnung, was passiert, wenn mehrere davon Laufzeit-Packages verwenden, und ich will es auch nicht herausfinden. Das ist in jedem Fall ein überaus vermeidenswertes Szenario.

    In deinem Fall ist das aber alles sinnlos: der Exception-Dialog ist ein Eingriff in die Innereien der RTL, und das wird über mehrere Compiler- und RTL-Versionen hinweg ganz sicher nicht klappen. Einzige Möglichkeit: die DLL mit C++Builder 6 und dessen Laufzeitpackages neukompilieren.



  • Vielen Dank audacia für die schnelle und sehr informative Hilfe.
    Das dies nicht funktioniert hatte ich mir leider schon fast gedacht.
    Nun muß ich mal schauen wie ich weiter mache.

    MfG Stephan



  • Hallo zusammen

    Nachdem meine DLL nun funktioniert, ist mir aufgefallen, daß der Exception Dialog nur im Main Thread aufgerufen wird.
    Hat hierfür jemand eine Erklärung?
    Außerdem ist mir aufgefallen, daß wenn ich den Exception Dialog nicht mit kompiliere und eine AV im Thread (nicht Main Thread) auslöse, wird diese nur im Debugger angezeigt. Ist dies normal?

    MfG Stephan



  • Stephan schrieb:

    Hat hierfür jemand eine Erklärung?

    Nicht ohne JclDebug näher zu studieren. Sieh doch einfach mit dem Debugger nach, was passiert, wenn eine Exception in einem sekundären Thread nicht gefangen wird.



  • Hallo audacia

    Das hatte ich versucht.
    Es passiert nichts erkennbares für den User. Der Thread wird einfach beendet.
    Dies hat jedoch nichts mit JclDebug zu tun.
    Sobald in einem Thread eine AV auftritt, wird dieser ohne irgendwelche Rückmeldung beendet. Ist dies normal?

    MfG Stephan


Log in to reply