Autor Beitrag
Franky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 18

Windows 98; xphomeedition
Delphi 2007 RAD Studio
BeitragVerfasst: Fr 06.02.09 16:15 
Tach Leute :)
Dieses Thema ist allgemein, je nachdem, ob und wie es sich entwickelt, könnte man später ja mal ein FAQ raus machen.
Also:
Ich bin Student und programmiere im Studium mit Delphi. Ich bin als Programmierer keineswegs unerfahren, aber in Delphi noch relativ neu.

Daher meine Frage: Wie finde ich Fehler in Delphi

1.)Wenn ich mich in der Syntax verschreibe, meldet Delphi mir das und alles ist (meist) in Butter. Da gibt es so keine Probleme.Aber:
2.)Wenn der Fehler sich nicht in der Syntax versteckt, wird es nach meiner Erfahrung haarig. Denn ausser "Lese/Schreibfehler" bzw. Zugriffsverletzung habe ich da in Delphi noch keine speziellen Fehlermeldungen gesehen.
Als PureBasic-gewöhnter (nicht alle, aber viele Fehler werden während der Laufzeit näher erklärt) Programmierer bin ich bei Delphi immer etwas hilflos, wenn ein Fehler auftaucht.
Was ich schon kenne:
-Ich kenne Haltepunkte und nutze sie auch
-ich weiß auch, dass man Variablenwerte auslesen kann, wenn man die Maus drauf hält.
-Eine Zugriffsverletzung bei 0000000000000CC oder so weißt meist auf eine Variable innerhalb eines NIL-Pointers hin. Das kann aber auch wieder verschiedene Ursachen haben.

Wie geht ihr vor, wenn ihr einen Fehler habt?
Mal ein Beispiel, wie ich in PB arbeite:
Szenario: Absturz in einer Schleife nach 580 problemlosen Durchläufen.
Ich nutze "Debug", um mir einen Wert aus zu geben oder auch mehrere. So kann ich mir die Werte ausgeben lassen, gucken, wo er abstürzt und mir evtl. auch die Werte ansehen, die im Durchlauf davor ausgegeben wurden.
Habe ich z.B. einen Pointer, der jeweils einen Zeiger auf den nächsten Pointer beinhaltet (halt eine LinkedList) und überschreibe ihn in der Schleife aus versehen, seh ich direkt: Am anfang ist er noch da, am Ende nicht mehr. Ergo liegt der Fehler da zwischen. Das kann ich nach und nach eingrenzen, falls es noch in einer Unterprocedure liegt.


Wie würdet ihr sowas in Delphi angehen unter Klausurvorraussetzungen, d.h.:
-Keine externen Programme, nur das RAD-Studio
-Keine externen Libs oder "such mal bei Google" ;)

PS: Mir ist klar, dass es kein Allheil-Mittel gibt. Aber wenn ich in der Klausur nicht wie n Ochs vorm Berg stehe, hilft mir das schon ungemein ;)

_________________
Hier könnte ihre Werbung stehen
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 06.02.09 16:36 
Ja, zum Thema debuggen bereite ich gerade Videotutorials mit schriftlicher / bildlicher Beschreibung für die entsprechende Sparte im Forum vor, aber das dauert leider noch etwas, mir fehlen noch ein paar gute Beispiele usw.

user profile iconFranky hat folgendes geschrieben Zum zitierten Posting springen:
-Ich kenne Haltepunkte und nutze sie auch
-ich weiß auch, dass man Variablenwerte auslesen kann, wenn man die Maus drauf hält.
Kennst du auch Strg + F7? Damit kannst du Ausdrücke auswerten, also nicht nur einzelne Variablen sondern auch sowas wie "x + y", wenn das zwei Variablen sind.
In dem Fenster, das dann erscheint, gibt es auch den Befehl Watch. Damit kannst du den Audruck zu einer Liste überwachter Ausdrücke hinzufügen, deren Werte du in einer Liste links siehst beim Debuggen (standardmäßig im RAD Studio, oberhalb der lokalen Variablen). Diese werden automatisch ausgewertet.

Dann kannst du auf einen Haltepunkt auch mit rechts klicken und dort eine Bedingung hinzufügen. Zum Beispiel in einer for-Schleife "i >= 100", damit der Haltepunkt erst angesprungen wird, wenn i diesen Wert hat. So kannst du die ersten x Schleifendurchläufe o.ä. überspringen und danach debuggen.
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Fr 06.02.09 20:58 
Eine oft uebersehen Moeglichkeit, ist die Ausgabe von Debug-Informationen mittels Write/WriteLn. Das ist naemlich durchaus auch in GUI-Programmen moeglich, man muss lediglich dem Linker sagen, er soll eine Konsole-Applikation erstellen. Das schoene dabei: Der Inhalt der Konsole benoetigt kein aktives Programm, im Gegensatz zu den GUI-Fenstern, die ohne Redraw keinen Inhalt haben.
Nachteil ist allerdings, dass Write/WriteLn einen Laufzeitfehler ausloest, wenn es sich nicht um eine Konsole-Anwendung handelt.

Alternativ kann man natuerlich immer auch in eine Datei schreiben.

Wusstest Du uebrigens, dass Du im Callstack einen Eintrag doppelklicken kannst? Dann zeigt Dir Delphi den dazu gehoerigen Sourcecode an und auch, soweit verfuegbar, die dort gueltigen lokalen Variablenwerte.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 07.02.09 14:44 
Was sich auf jeden Fall auszahlt ist es, von vornherein versuchen sauberen Code zu schreiben. Sich zu überlegen, was zusammen gehört und was nicht, wo welcher Code hingehört und wo nicht. Klare Schnittstellen zwischen Klassen schaffen. Sauberes Exception Handling; dazu gehört, dass bei einer Exception schon ausgeführte Schritte wieder rückgängig gemacht werden, bzw. Änderungen erst am Schluss übernommen werden. Assertions verwenden (z.B. um Annahmen zu überprüfen). Keine "dangling Pointers/References" hinterlassen. Nicht mit Pointern arbeiten. Patterns sinnvoll einsetzen. OOP-konformen Code schreiben. ReportMemoryLeaks einschalten. Range/Overflow checking einschalten. Unit Tests. Falls Versionierungssystem benutzt wird vor dem Einchecken schnell den Diff durchschauen. Sinnvolle Dokumentation (vor allem bei Workarounds). Usw. Da gibt's wohl ganze Bücher drüber ;)

Das beantwortet deine Frage nicht direkt, aber wenn du halt gewisse Annahmen beim Debuggen machen kannst, findest du den Fehler viel schneller bzw. du machst insgesamt viel weniger Fehler. Wenn du einen Fehler hast, dann Call-Stack anschauen, Debug-Messages ausgeben (z.B. OutputDebugString), Variableninhalte anschauen, Einzelschritt. Was wohl am meisten hilft ist die Erfahrung die Fehler richtig deuten zu können...
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 07.02.09 17:01 
Anstatt die Krücke Write\WriteLn für GUI zu missbrauchen, kann man auch einfach OutputDebugString nutzen, was im Delphi-Debugger (aber auch ohne) über Tools wie DebugMon mitgelesen werden kann.

Kann man in Delphi soweit treiben, dass man je nach Formatierung der Meldung sogar unterschiedliche Farben vergibt (IIRC) und somit ein richtig gutes Log hat, was einem das Wichtigste gleich so sagt.

Was auch immer erwähnenswert ist, ist die Möglichkeit, sich die Debug-Symbole extern erzeugen zulassen (Mapfiles). Damit kann man bei Zugriffsverletzungen auch wenn diese außerhalb der IDE auftauchen noch recht gut Rückschlüsse auf den Fehler bekommen (es gibt Ausnahmen, aber gut, dazu gleich mehr ;-)).

Nämlich dann, wenn man einen Buffer Overrun drin hat und damit die Return-Adresse auf dem Stack überschrieben wurde. In solchen Fällen erhält man leider gern einmal die falsche Fehleradresse in der eigentlichen Exception-Meldung. Hier hilft es dann, sich einen Stacktrace zu organisieren. Erwähnt seien hier das quelloffene und freie Omorphia Debug Interface oder kommerzielle Lösungen wie EurekaLog und madExcept.

Das Omorphia Debug Interface hat zudem den Vorteil, dass es von der Anwendung auch ohne Vorhandensein eines Fehlers genutzt werden kann, und somit z.B. auch interne Methodennamen aufgelöst werden können (Debug-Infos vorausgesetzt), oder man sich den aktuellen Stacktrace organisieren kann, um dort ggf. Auswertungen durchführen zu können. Im ODI sind zudem Möglichkeiten zum Nutzen von OutputDebugString enthalten, wodurch Log-Meldungen automatisch mit Symbol-Informationen an die IDE geschickt werden (sehr praktisch übrigens ;-))

Ansonsten aber schon so wie es user profile icondelfiphan sagt: Am besten man übt sich in Fehlerfrei Programmieren(tm).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Franky Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 18

Windows 98; xphomeedition
Delphi 2007 RAD Studio
BeitragVerfasst: Mo 09.02.09 18:51 
Danke für die Antworten, hat mir ne ganze Menge geholfen, heute während der Klausur einen Fehler zu finden. :D
Tja, wat soll man sagen, ausser, dass meine Note zweistellig binär (vorkomma, nachkomma) das doppelte dessen beträgt, was es im uns gewöhnten Zahlensystem sagt. 8)

_________________
Hier könnte ihre Werbung stehen
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 09.02.09 19:07 
user profile iconFranky hat folgendes geschrieben Zum zitierten Posting springen:
Danke für die Antworten, hat mir ne ganze Menge geholfen, heute während der Klausur einen Fehler zu finden. :D
Tja, wat soll man sagen, ausser, dass meine Note zweistellig binär (vorkomma, nachkomma) das doppelte dessen beträgt, was es im uns gewöhnten Zahlensystem sagt. 8)

BCD oder Greycode?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.