Autor |
Beitrag |
Thom
      
Beiträge: 70
Erhaltene Danke: 5
Delphi 10 Seattle Prof.
|
Verfasst: Mo 27.01.14 21:30
Nein - das geht wirklich nicht. Wenn in der Zeile Assert(false); steht, ermittelt und übergibt der Kompiler automatisch die Zeilennummer. Willst Du das nicht, mußt Du das manuell machen und bei jeder Quelltextveränderung anpassen (was bei 150 Stellen sicher wenig Spaß macht).
Ist es aber nicht egal, ob Du Assert in eine Zeile schreibst und den Aufruf der Log-Funktion in die nächste oder alles in eine Zeile? Notfalls würde ja auch
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var CurrentLineNumber: Integer;
procedure MyAssertErrorProc(const Message, Filename: String; LineNumber: Integer; ErrorAddr: Pointer); begin CurrentLineNumber:=LineNumber; end; [...] if ... then begin Assert(false); TextOutPut(CurrentLineNumber, s, ...); end; [...] |
statt
Delphi-Quelltext 1: 2:
| if ... then TextOutPut(Assert(0=1), s, ...); |
gehen. Oder? Funktioniert natürlich nur, wenn Assert aus dem Hauptthread heraus aufgerufen wird (wegen der globalen Variable).
Für diesen Beitrag haben gedankt: galagher
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 27.01.14 22:17
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Blup
      
Beiträge: 174
Erhaltene Danke: 43
|
Verfasst: Di 28.01.14 11:53
Für den Anwender ist so ein Log mit Zeilennummern sicher nicht sinnvoll.
Da sollte nur stehn welche Funktion ausgeführt wurde und mit welchem Ergebnis.
Für unbekannte Fehler kann man Tools wie "Eurekalog" einsetzen.
Dieses liefert im Fehlerfall ein Protokoll mit kompletten Aufrufstapel und Zeilennummern.
Dann gibts da noch die sogenannten "Profiler".
Diese arbeiten als eine Art Precompiler und fügen für jede überwachte Methode automatisch Code ein.
Dieser protokolliert den Aufruf und das Verlassen der Methode, die Zeit usw..
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Di 28.01.14 21:03
Blup hat folgendes geschrieben : | Für den Anwender ist so ein Log mit Zeilennummern sicher nicht sinnvoll. |
Der Anwender bin ich!
Habe jetzt den Code konsequent mit Assert umgestellt, Assert steht zusammen mit dem entsprechenden Code, auf den es sich bezieht, in einer Zeile. Also habe ich jetzt zwei Anweisungen in einer Zeile stehen (pfui!), aber ist halt so. Umschlossen mit teilweise sinnlosem begin - end. Zwar ist es so wenigstens einheitlich, aber eben einheitlich pfui.
Wie herrlich wäre doch die (Delphi)-Welt, wenn man an Prozeduren/Funktionen einfach Prozeduren/Funktionen als Parameter übergeben könnte - uneingeschränkt, versteht sich!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 28.01.14 21:27
galagher hat folgendes geschrieben : | Wie herrlich wäre doch die (Delphi)-Welt, wenn man an Prozeduren/Funktionen einfach Prozeduren/Funktionen als Parameter übergeben könnte - uneingeschränkt, versteht sich! |
Naja, theoretisch...
Delphi-Quelltext 1:
| LogCurrent(procedure begin Assert(False) end, 'Logstring'); | Das geht ja durchaus...
Also vollständig: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| type EAssertionFailedEx = class(EAssertionFailed) private FFilename: string; FMessage: string; FLineNumber: Integer; FErrorAddr: Pointer; public constructor Create(const AMessage, AFilename: string; ALineNumber: Integer; AErrorAddr: Pointer); property Message: string read FMessage write FMessage; property Filename: string read FFilename write FFilename; property LineNumber: Integer read FLineNumber write FLineNumber; property ErrorAddr: Pointer read FErrorAddr write FErrorAddr; end;
constructor EAssertionFailedEx.Create(const AMessage, AFilename: string; ALineNumber: Integer; AErrorAddr: Pointer); begin inherited Create(AMessage); FMessage := AMessage; FFilename := AFilename; FLineNumber := ALineNumber; FErrorAddr := AErrorAddr; end;
procedure AssertionFailed(const Message, Filename: string; LineNumber: Integer; ErrorAddr: Pointer); begin raise EAssertionFailedEx.Create(Message, Filename, LineNumber, ErrorAddr); end;
procedure LogCurrent(const AAssertProcedure: TProc; const ALogText: String); begin try AAssertProcedure; except on E: EAssertionFailedEx do ShowMessage('Logeintrag:'#13#10 + E.Message + #13#10 + E.Filename + #13#10 + IntToStr(E.LineNumber)); end; end;
procedure TForm53.FormCreate(Sender: TObject); begin AssertErrorProc := AssertionFailed; LogCurrent(procedure begin Assert(False) end, 'Logstring'); end; |
Für diesen Beitrag haben gedankt: galagher
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Di 28.01.14 21:57
jaenicke hat folgendes geschrieben : | galagher hat folgendes geschrieben : | Wie herrlich wäre doch die (Delphi)-Welt, wenn man an Prozeduren/Funktionen einfach Prozeduren/Funktionen als Parameter übergeben könnte - uneingeschränkt, versteht sich! | Naja, theoretisch... |
Praktisch sehe ich mir das morgen an, mal sehen!
Wie gut, dass ich nicht schon alle zwei Kopien*) der .pas-Datei überschrieben habe!
*) Habe immer zwei Kopien meiner Projektdateien: Eine in einem speziellen Ordner, eine auf USB-Stick.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 28.01.14 23:19
galagher hat folgendes geschrieben : | Wie gut, dass ich nicht schon alle zwei Kopien*) der .pas-Datei überschrieben habe! |
Kopien? Nicht dein Ernst, oder?
Hast du wirklich kein SVN-Repository oder ähnliches, in dem deine Quelltexte liegen?
// EDIT:
Ich nutze privat wie im Büro den VisualSVN Server:
www.visualsvn.com/server/
Kostenlos in der kleinen Version und absolut simpel zu benutzen.
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mi 29.01.14 03:23
Ich stör ja nur ungern eure lustigen Hacks, aber die LineInfo aus den Debuginfos auszulesen ist wirklich keine Option? Ich mein, ja, Delphi nutzt da ein abgedrehtes proprietäres Dateiformat ohne jeden Support von irgendwas, aber so schwierig ist das jetzt auch nicht (siehe BenBE's Omorphia OmMap).
Nachtrag: Oh, und @Versionskontrolle: ja, Projekte mit mehr als 100 Zeilen ohne Versionskontrolle sind grob fahrlässig. Passiert mir auch ab und zu noch, aber es wird seltener...
Und zu SVN sag ich mal nix - es ist immer noch besser als gar kein System zu nutzen.
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 29.01.14 07:10
Martok hat folgendes geschrieben : | Und zu SVN sag ich mal nix - es ist immer noch besser als gar kein System zu nutzen. |
SVN haben wir nur genommen, weil Git und Mercurial beide gar nicht oder nicht stabil als Dienst zum Laufen zu bekommen waren.
Ich sehe jetzt, dass es z.B. so etwas gibt:
bonobogitserver.com/
Hätte ich das seinerzeit gefunden (wenn es das da schon gab), hätten wir vielleicht auch das genommen.
So einfach wie VisualSVN (einfach nen Dienst) ist es dennoch nicht.
Die Debuginformationen auslesen dürfte mit einem (ggf. partiellen) Stacktrace am einfachsten sein, und das geht z.B. mit den JEDIs ja auch direkt, wie ich schon vorgeschlagen hatte.
Aber es macht das ganze natürlich auch nicht schneller. Da ist vermutlich sogar die Assertion schneller, oder?
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mi 29.01.14 15:53
jaenicke hat folgendes geschrieben : | Aber es macht das ganze natürlich auch nicht schneller. Da ist vermutlich sogar die Assertion schneller, oder? |
Ist halt die Frage wie man's macht
Für BitSpace habe ich darauf basierend einen instrumentierenden Profiler entwickelt, der aus der Adresse (Get_pc_addr) beim Aufruf die Funktion/Zeile herleitet, das ist also durchaus nah-echtzeit machbar. Overhead ist im Schnitt bei <0.1ms/call.
Delphi-Quelltext 1: 2:
| {$DEFINE __PROFENTER:=uutlEmbeddedProfiler.ProfilerEnterProc(Get_pc_addr); try} {$DEFINE __PROFLEAVE:=finally uutlEmbeddedProfiler.ProfilerLeaveProc; end;} | (FPC hat tokenbasierte Macros)
Ist leider nicht ganz vergleichbar, da man in FPC über die Unit lineinfo direkt Zugriff auf die Symbole seiner Anwendung bekommt. Die lookup-Ergebnisse werden allerdings auch gecached, um jede Adresse nur einmal abfragen zu müssen. Ansonsten wäre das massiv IO-Bound auf der Symboldatei.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| i:= fAddressCache.IndexOf(Events[WritePtr].Func); if i<0 then begin ce.Name:= ''; ce.Line:= 0; ce.Src:= ''; GetLineInfo(Events[WritePtr].Func,ce.Name,ce.Src,ce.Line); fAddressCache.Add(Events[WritePtr].Func, ce); end else ce:= fAddressCache.Data[i]; |
Womit wir allerdings wieder beim Problem vom Anfang wären. FPC verwendet in der Standardeinstellung Dwarf(2,3?)-Symbole, die sind einfacher zu lesen als Delphi oder TDB. Aber das könnte man ja aus den Jedis klauen, man muss ja nicht die komplette Lib nur dafür reinziehen...
Okay, ich hab ein paar Multithreading-Tricks und lustige Datenstrukturen verschwiegen die das so schnell machen, aber bisschen Geheimnisse haben wir ja auch 
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mi 29.01.14 21:33
jaenicke hat folgendes geschrieben : | galagher hat folgendes geschrieben : | Wie herrlich wäre doch die (Delphi)-Welt, wenn man an Prozeduren/Funktionen einfach Prozeduren/Funktionen als Parameter übergeben könnte - uneingeschränkt, versteht sich! | Naja, theoretisch...
Delphi-Quelltext 1:
| LogCurrent(procedure begin Assert(False) end, 'Logstring'); | Das geht ja durchaus... |
Ich habe deinen Code eingebaut, an mein Projekt angepasst und es läuft! Phantastisch! Hätte das ohne deine Hilfe nie hinbekommen, vielen Dank!
jaenicke hat folgendes geschrieben : | galagher hat folgendes geschrieben : | Wie gut, dass ich nicht schon alle zwei Kopien*) der .pas-Datei überschrieben habe! | Kopien? Nicht dein Ernst, oder?
Hast du wirklich kein SVN-Repository oder ähnliches, in dem deine Quelltexte liegen?  |
Nein, wenn du eine Versionskontrolle meinst. Ich habe nichts dergleichen. Ich kopiere einfach alle Dateien, das ist alles. Da ich ja bloss hobbymässig programmiere, reicht das doch!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 30.01.14 10:20
galagher hat folgendes geschrieben : | Nein, wenn du eine Versionskontrolle meinst. Ich habe nichts dergleichen. Ich kopiere einfach alle Dateien, das ist alles. Da ich ja bloss hobbymässig programmiere, reicht das doch! |
Hobbymäßig oder nicht, es ist trotzdem viel einfacher. Denn wenn du z.B. gerade etwas ausprobierst, brauchst du nur auf vergleichen gehen und siehst deine Änderungen usw., und du weißt auch was aktuell ist. Wenn du mehrere Kopien machst, kann es dir passieren, dass du an der falschen änderst oder ähnliches.
Das hat nichts damit zu tun, ob man das beruflich macht oder nicht. Ich mache das bei meinen privaten Projekten ganz genauso. Einfach weil es sehr viel einfacher ist. Und für Backups brauche ich nur immer das Repository sichern.
Für diesen Beitrag haben gedankt: Martok
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Do 30.01.14 21:04
jaenicke hat folgendes geschrieben : | kann es dir passieren, dass du an der falschen änderst oder ähnliches. |
Man muss halt wissen, was man tut!
Wenn ich so etwas erst einmal gesehen habe, werde ich dir sicher zustimmen, aber da ich es ja nicht kenne... 
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
haentschman
      
Beiträge: 285
Erhaltene Danke: 33
DX10 Berlin Professional
|
Verfasst: Sa 01.02.14 10:09
Moin...
Zitat: | aber da ich es ja nicht kenne... |
...was der Bauer nicht kennt, das frißt er nicht.
Ich sage es mal einfacher... Ich hatte vor Jahren die gleiche Meinung wie du. Dann habe ich mich mich mal mit SVN beschäftigt. Heute kann ich mir nicht mehr vorstellen wie es ohne gegangen ist. Wenn man die Vorzüge, vor Allem die Übersicht über den Code, erkannt hat... ohne Versionskontrollsystem niemals. 
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 02.02.14 00:48
Ich habe eben mal einen kleinen Überblick dazu geschrieben bzw. gebildert wie man ein solches SVN-Repository installiert und nutzt:
www.entwickler-ecke....ewtopic.php?p=683811
Die Bilder stammen von einer virtuellen Maschine mit Windows 7.
|
|
|