AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Die Delphi-IDE Zur Laufzeit, Zeilennummer feststellen
Thema durchsuchen
Ansicht
Themen-Optionen

Zur Laufzeit, Zeilennummer feststellen

Ein Thema von Eppos · begonnen am 13. Apr 2018 · letzter Beitrag vom 18. Apr 2018
Antwort Antwort
jus

Registriert seit: 22. Jan 2005
350 Beiträge
 
Delphi 2007 Professional
 
#1

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 15:01
Hallo,

ich verwende zum Ermitteln der Zeilennummer die JCL, da ich in meinem Programmen häufig Fehler in eine Logdatei reinschreibe, der coole Tipp kam von diesem Forum hier. Der Vorteil ist, dass JCL eigentlich nicht wirklich was kostet.
Meine Logfunktion schaut in etwa so aus:
Delphi-Quellcode:
implementation
uses JCLDebug;

procedure Log(S: String);
var
  msg: String;
  Year, Month, Day, Hour, Min, Sec, MSec, H: Word;
begin
  DecodeTime(now, Hour, Min, Sec, MSec);
  msg := Format('%.2d:%.2d:%.2d.%.3d %s:%u (%s) "%s"',[Hour,Min,Sec,MSec,FileByLevel(1), LineByLevel(1), ProcByLevel(1), S]);

  // hier schreibe ich die Fehlermeldung in eine Datei oder lasse es im Programm ausgeben
  //......
end;
Meine Logdatei schaut dann so aus, wobei nach dem Unitnamen die Zeilennummer ist.
Code:
23:03:53.262 Unit1.pas:2787 (TForm1.Update_CmB_Printer) "Fehler! Der Druckername "TM88IV" konnte nicht unter den installierten Druckern gefunden werden."
23:03:53.264 Unit1.pas:2794 (TForm1.Update_CmB_Printer) "Der aktive Druckername wird auf "TMU290" gesetzt."
23:03:53.266 Unit1.pas:536 (TForm1.FillPrinterDataToGui) "Current printer model "TM88IV" match with "C:\ProgramData\XXX\XXX\PrinterInfo.xml"
23:03:53.268 PrinterLib.pas:1104 (PrinterXmlGetStandardFeedsources) "In C:\ProgramData\XXX\XXX\PrinterInfo.xml <feedsource name="01"> node no <borderless> found."
23:03:53.270 Unit1.pas:550 (TForm1.FillPrinterDataToGui) "C:\Users\abc\AppData\Roaming\XXX\MediaNotVisible found"
23:03:53.272 Unit1.pas:1172 (TForm1.LoadPresets) "---TForm1.LoadPresets---"
23:03:53.273 Unit1.pas:1173 (TForm1.LoadPresets) "TForm1.LoadPresets: Suche alle Presets in C:\Users\abc\AppData\Roaming\XXX\PRESET\*.epl mit dem Druckermodel TM88IV"
23:03:53.282 Unit1.pas:1231 (TForm1.LoadPresets) "INVALID: C:\Users\abc\AppData\Roaming\XXX\PRESET\14_20150730_190038.epl"
Die JCL Debugfunktionenn können natürlich viel mehr wie z.B. Stacktrace ausgeben usw. siehe den alten Beitrag hier.

Lg,
jus

Geändert von jus (17. Apr 2018 um 15:07 Uhr)
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#2

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 15:01
Zitat:
Der Vorteil ist, dass JCL eigentlich nicht wirklich was kostet.
Bis auf einen kleinen Hinweis im Programm, dass es JCL verwendet, sollte es nichts kosten

Könntest du eventuell ProcByLevel erklären?

Wenn Prozedur A einen Fehler hat und Prozedur B_Log aufruft und letztere wieder ProcByLevel(0), dann habe ich im Log den Namen B_log stehen.
Heißt ProcByLevel(1) nur "gehe eine Prozedur weiter zurück? Wenn ja, was, wenn ich X Prozeduren habe die sich hintereinander aufrufen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.557 Beiträge
 
Delphi 12 Athens
 
#3

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 15:11
Zitat:
Heißt ProcByLevel(1) nur "gehe eine Prozedur weiter zurück?
Ja, aber du solltest das Programm mit Stack-Frames kompileren, denn sonst erkennt der Stacktrace kleinere Funktionen garnicht.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#4

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 15:12
Hat das irgendwelche Nachteile bezüglich der Sicherheit des fertigen Kompilats?

FileByLevel, LineByLevel, ProcByLevel. Was aber wenn ich nicht wie weit ich zurück muss? Ist mir mir gerade nicht so, aber für die Zukunft wäre das interessant.

Hier nur ein Beispiel.
In meiner Mainform ist eine Prozedur AppExceptionHandler.
Die ruft eine Prozedur doLog in einer Log-Unit auf und doLog ruft letzten Endes die Prozedur auf, die das Log schreibt.
Gehe ich 3x zurück, lande ich bei Vcl.Forms.pas.

Geändert von günni0 (17. Apr 2018 um 15:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.557 Beiträge
 
Delphi 12 Athens
 
#5

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 15:23
Was aber wenn ich nicht wie weit ich zurück muss?
Sowas hab ich grade in Postgres bei einer Funktion eingebaut, im Grunde mit einer Blacklist.

Die Funktion wird auch von Anderen aufgerufen, wobei Einige dafür auch nur interne Loggingfunktionen sind.
Ich gehe den Stacktrace nun einfach so lange rückwärts, bis ich einen "mir unbekannten" Funktionsnamen finde und dieser kommt ins Log.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#6

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 15:34
Gerade mal mit einer Schleife und ProcByLevel nachgebaut.


Zitat:
TLogFunctions.doExceptionLog
Form.Main.TForm1.AppExceptionHandler
Forms.TApplication.HandleException
Classes.StdWndProc$qqsp6HWND__uiuiui
FileByLevel dementsprechend
Zitat:
uLog.pas
<projektname>.Form.Main.pas
Vcl.Forms.pas
System.Classes.pas
Danach kommt nix mehr. Darf man bei sowas keinen eigenen HandleException haben?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.557 Beiträge
 
Delphi 12 Athens
 
#7

AW: Zur Laufzeit, Zeilennummer feststellen

  Alt 17. Apr 2018, 16:46
Application.HandleException ist da, wo es bei dir schon raus ist.

Delphi-Quellcode:
function HandleMessage;
try
  CallWindowsEvents; // hier hat es in einer unterfunktion geknallt
except
  HandleException; // aber hier ist dein HandleException-Event drin, also ist ein Stacktrace von HIER aus sinnlos
end
System.ExceptObject ... das entspricht dem on E: Exception im EXCEPT-Block
System.ExceptAddr ... hier hatte es geknallt
System.ReturnAddress ... mein Caller (bzw. der Befehl danach)

Schau dir mal die Exception-Klasse genau an. Da kann man sich für die Stacktrace-Behandlung registrieren.
Also während die Exception ausgelöst wird ... da kannst du den Stacktrace auslesen und innerhalb des aktuellen Exception-Objektes speichern. (Delphi bietet nur die Zugangspunkte, aber ohne eigene Funktion)
Und in der anschließenden Exceptionbehandlung kannst du über das Exception-Objekt an dessen Stacktrace wieder rankommen.
Ein Therapeut entspricht 1024 Gigapeut.
  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:41 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