Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Procedur-Namen in einer Exception ausgeben ..
motion - Fr 26.08.05 17:08
Titel: Procedur-Namen in einer Exception ausgeben ..
Wie lässt sich bei einer Exception der Compiler dazu veranlassen, den Prozedur- oder Funktionsnamen hineinzucompilieren?
Delphi-Quelltext
1:
| Raise Exception.CreateFmt('ungültiger Aufzählungstyp in Prozedur '+???,[]); |
Moderiert von Christian S.: Topic aus VCL (Visual Component Library) verschoben am Fr 26.08.2005 um 17:37
uall@ogc - Fr 26.08.05 17:12
nein das diese in der compilierten exe nicht mehr vorhanden sind (bzw. nicht mehr sein sollten)
BenBE - Fr 26.08.05 17:20
Das geht nur mit Zusatzsoftware wie
MADEXCEPT oder
EUREKALOG. Diese Software speichert sich Zusammen mit deiner EXE die Zeilen-Info-Daten und einige Bezeichner, wodurch die Prozeduren in denen ein Fehler auftrat ausgelesen werden können.
LigH - Fr 26.08.05 17:20
Wer sich so was selbst basteln wollte, könnte versuchen:
- globale String-Variable einführen
- am Anfang jeder Prozedur/Funktion vorherigen Stand zwischenspeichern und aktuellen Namen hineinspeichern
- am Ende jeder Prozedur/Funktion vorherigen Stand zurückspeichern
Macht aber bestimmt keinen Spaß. Wenn irgendwie möglich, besser an jeder riskanten Stelle einen eigenen try-except-Bereich verwenden und dort immer lokal sinnvolle Aktionen ausführen lassen. Oder mit Assertions arbeiten, wenn man riskante Zustände vorhersagen kann.
uall@ogc - Fr 26.08.05 17:22
DeDe bekommt auch die namen wieder raus, irgendwie müssten die da drin gespeichert sein nur wie weiß ich net oO
jedefalls die klassen-funktions-namen sind gespeichert
BenBE - Fr 26.08.05 17:52
Bei Klassen werden die Namen von published-deklarierten Methoden in der TypeInfo gespeichert.
Andere Programme arbeiten auch über die MAP-File, die man sich optional mit Delphi erzeugen kann. War heut erst wieder überrascht, was da alles drin steht ;-)
AXMD - Fr 26.08.05 17:57
BenBE hat folgendes geschrieben: |
Andere Programme arbeiten auch über die MAP-File, die man sich optional mit Delphi erzeugen kann. War heut erst wieder überrascht, was da alles drin steht ;-) |
Wie kann man die auslesen? Kann man daraus etwa schließen, wo die Adresse einer AV hinzeigt :shock: - Weil Map... nur so ein Gedanke
AXMD
BenBE - Fr 26.08.05 18:23
@MAP-File: Dort stehen har klein nahezu alle zum Debuggen relevanten Offsets drinne. Diese muss man sich dann nur noch anhand des Modul-Handles umrechnen (in die Virtuellen Adressen und kann daraus dann schließen "Exception ist etwa in der Zeile aufgetreten", indem man einen Stacktrace vornimmt, der jegliche aufrufenden Routinen umfasst (oder die eigentliche Exception-Stelle, die im Exception-Objekt gespeichert ist).
AXMD - Fr 26.08.05 18:26
BenBE hat folgendes geschrieben: |
@MAP-File: Dort stehen har klein nahezu alle zum Debuggen relevanten Offsets drinne. Diese muss man sich dann nur noch anhand des Modul-Handles umrechnen (in die Virtuellen Adressen und kann daraus dann schließen "Exception ist etwa in der Zeile aufgetreten", indem man einen Stacktrace vornimmt, der jegliche aufrufenden Routinen umfasst (oder die eigentliche Exception-Stelle, die im Exception-Objekt gespeichert ist). |
Hieße das (umgesetzt), dass man bei einer AV 123456 an Adresse 7890AB sagen könnte, dass sie etwa in Zeile XY aufgetreten ist? Wieviel Aufwand ist das?
AXMD
motion - Fr 26.08.05 19:36
Uiiih,
doch eine vielzahl von Ideen und Beteiligung an meinem Thread. Vielen Dank dafür.
Hmmm, ich hatte ja gehofft, das es doch eine Compiler- oder Systemvariable gibt, die man verwenden kann.
Ist dann leider doch nicht so einfach. Also muss ich es dann doch selbst als Konstante bei jedem Vorkommen einsetzen.
AXMD - Fr 26.08.05 19:56
motion hat folgendes geschrieben: |
Uiiih,
doch eine vielzahl von Ideen und Beteiligung an meinem Thread. Vielen Dank dafür.
Hmmm, ich hatte ja gehofft, das es doch eine Compiler- oder Systemvariable gibt, die man verwenden kann.
Ist dann leider doch nicht so einfach. Also muss ich es dann doch selbst als Konstante bei jedem Vorkommen einsetzen. |
Weniger aufwändig sind oben angesprochene Tools wie madexcept
AXMD
BenBE - Fr 26.08.05 20:06
Ist nicht kompliziert. Die Map-File zu parsen ist relativ einfach. Aus dieser kann man über relativ einfache Berechnungen auf die eigentliche Exception-Adrese schließen. Daraus die Zeilennummer zu ermitteln ist nur ne Sache von wenigen Programmzeilen ...
retnyg - Fr 26.08.05 20:35
BenBE hat folgendes geschrieben: |
dieser kann man über relativ einfache Berechnungen auf die eigentliche Exception-Adrese schließen. Daraus die Zeilennummer zu ermitteln ist nur ne Sache von wenigen Programmzeilen ... |
dann sollte es für dich ja kein problem sein die paar zeilen hier zu posten, oder ?
BenBE - Fr 26.08.05 20:50
Fertigen Source zum Direkteinbau hab ich ATM nicht da, werd mir aber für eigengebrauch im Zusammenhang mit
Omorphia [
http://www.omorphia.de/] demnächst mal eine Unit schreiben. Guckt euch dazu doch einfach mal eine MAP-Datei von Delphi mit Notepad an ... Dann sollte eigentlich klar sein, wie das mit dem Auslesen geht ...
AXMD - Fr 26.08.05 21:21
retnyg hat folgendes geschrieben: |
BenBE hat folgendes geschrieben: | dieser kann man über relativ einfache Berechnungen auf die eigentliche Exception-Adrese schließen. Daraus die Zeilennummer zu ermitteln ist nur ne Sache von wenigen Programmzeilen ... |
dann sollte es für dich ja kein problem sein die paar zeilen hier zu posten, oder ? |
[OT]Eine Zeilennummernberechnung wär mal was für die Leute, die Betriebssysteme, Bootloader, Shells etc. schreiben wollen :mrgreen: Weil sowas wär wirklich nice to have - weil dann kann man mit Betastestermeldungen, die mit AVs zu tun haben, endlich mehr anfangen :)[/OT]
AXMD
BenBE - So 28.08.05 13:29
Hab mal eine erste kleine Test-Unit fertig...
Liest bis jetzt Unit-Namen und Zeilennummern. Das Publics-Segment der MAP-File wird noch nicht geparst, das kommt aber später für Omorphia noch in die Unit mit rein (später erhältlich unter
ODbgMapfile.pas [
http://viewcvs.omorphia.de/omorphia/library/ODbgMapfile.pas]).
Zur Zeit sieht ein Stacktrace mit Debug-DCUs und voller MAP-File bei mir so aus:
Stacktrace mit detaillierter Mapfile und Debug-DCUs:
Testprojekt mit besagter Unit siehe Anhang.
WICHTIG: Damit das Programm DebugInfos findet muss die MAP-File ATM im Arbeitsverzeichnis der EXE liegen. Zusätzliche MAP-Files für Zusatz-DLLs werden automatisch erkannt, wenn diese DLLname.map heißen und auch im Arbeitsverzeichnis liegen.
HINWEIS: Mapfile-Parser bisher nur mit D7 getestet. Für andere Compiler kann es notwendig sein, den Parser leicht abzuändern.
ACHTUNG: Bei Verwendung in eigenen Programmen bitte Credits halten und meinen Namen oder Projekt Omorphia sichtbar in der Aboutbox oder Readme erwähnen. Unit steht unter LGPL!
BenBE - So 28.08.05 14:19
Kleine Sache noch:
uall@ogc wies mich grad auf nen Fehler in dem Demo hin, was zwar nix mit der eigentlichen Adress-Umsetzung zu tun hat, aber dennoch unschöne Effekte erzeugt ;-)
Die Button1Click-Methode muss folgendermaßen abgeändert werden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| Procedure TForm1.Button1Click(Sender: TObject); Label Test; Var X: Pointer; Begin Memo1.Lines.BeginUpdate; try Memo1.Lines.Clear;
Test: Asm MOV EAX, OFFSET [Test] MOV DWORD PTR [X], EAX End;
Caption := AddressToLocation(X);
GetDetailedStackTrace(Memo1.Lines, 100); finally Memo1.Lines.EndUpdate; End; End; |
Ich arbeite mit uall noch an einer etwas verbesserten Version zusammen, da noch einige Unstable SourceFragments enthalten sind ;-) Neuer DL folgt soweit die Unit vollständig stäble ist ...
Die eingebundene INC-File von Omorphia wird ATM noch nicht zwingend benötigt; dient einzig der Compiler- und Platform-Erkennung.
worm - So 28.08.05 15:43
AXMD hat folgendes geschrieben: |
Hieße das (umgesetzt), dass man bei einer AV 123456 an Adresse 7890AB sagen könnte, dass sie etwa in Zeile XY aufgetreten ist? |
Wenn Du mit Delphi arbeitest, kannst Du dann nicht einfach
'Suchen' -> 'Laufzeitfehler suchen...' nutzen? :gruebel:
BenBE - So 28.08.05 15:50
worm hat folgendes geschrieben: |
AXMD hat folgendes geschrieben: | Hieße das (umgesetzt), dass man bei einer AV 123456 an Adresse 7890AB sagen könnte, dass sie etwa in Zeile XY aufgetreten ist? | Wenn Du mit Delphi arbeitest, kannst Du dann nicht einfach 'Suchen' -> 'Laufzeitfehler suchen...' nutzen? :gruebel: |
Jain. Die Funktion "Laufzeitfehler suchen" funktioniert nur dann, wenn die EXE aus dem Source der IDE generiert wurde und der Source seit dem nichtmehr verändert wurde. Oftmals ist man aber schon einige Schritte weiter, so dass Source und EXE nicht mehr zusammenpassen. AV-Adressen sind dann sinnlos. Da hilft dann schon eher eine Mapfile, wie sie von Delphi generiert wird. Dort stehen alle wichtigen Infos drin, die man brauch. Selbst, wenn man schon tausende Zeilen Source weiter ist, stimmt die Mapfile (zur jeweiligen EXE-Version). Nun brauch man nur noch die Adresse dort nachschlagen und erhält die Source-Stelle. Nix anderes macht mein Demo ...
Achso, da wir hier ungeduldige User zu haben scheinen: Die DEMO braucht etwa 1-2 Minuten für den Stacktrace. Also: Geduldig sein!!!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!