Registriert seit: 23. Sep 2002
Tutorial
Debugging in Delphi für Anfänger und Fortgeschrittene
Autor: MaBuSE für www.delphipraxis.net
Stand: 24.02.2005
(c) 2004-2005, MaBuSE
Es wurden Teile der Onlinehilfe von Delphi 7 verwendet
(c) 1995-2002 Borland Software Corporation
Vielen Dank auch an sakura, alcaeus und jfheins für Anregungen und Korrekturlesen
Mein besonderer Dank für die Arbeit in der DP und Unterstützung für mich geht an:
Daniel, Sakura, Gerome und an alle Moderatoren
Warum dieses Turorial?
Mir ist aufgefallen, dass einige Mitglieder der DP nicht wissen wie man Delphi Programe debuggt / bzw. was der Debugger alles kann.
Ich werde hier in dem Tutorial das Debugging anhand von Delphi 7 zeigen. Das meiste sollte sich auch auf Delphi Versionen kleiner 7 übertragen lassen.
Eine Beschreibung der in Delphi 2005 hinzugekommenen Dinge wird sicherlich folgen
- Ein kleines Inhaltsverzeichnis: (Stichwortsammlung)
- Was ist Debugging?
- Der Debugger der Delphi IDE - Einführung
- Die möglichen Funktionen einzeln erklärt
- Gesamte Routine [F8]
- Einzelne Anweisung [F7]
- Nächste Quelltextzeile [Umsch + F7]
- Zur Cursorposition gehen [F4]
- Ausführung bis Rückgabe [Umsch + F8]
- Ausführungsposition anzeigen
- Programm Pause [F12 im laufendem Programm]
- Programm zurücksetzen [Strg + F2]
- Untersuchen
- Auswerten/Ändern [Strg + F7]
- Ausdruck hinzufügen [Strg + F5]
- Haltepunkt hinzufügen
- Haltepunkte (Breakpoints)
- Alle Haltepunkte in Delphi haben einige Gemeinsamkeiten
- Quelltexthaltepunkte
- Ungültige Haltepunkte
- Adresshaltepunkte
- Datenhaltepunkte
- Die Debug Fenster
- Haltepunkte [Strg + Alt + B]
- Aufruf-Stack [Strg + Alt + S]
- Überwachte Ausdrücke [Strg + Alt + W]
- Lokale Variablen [Strg + Alt + L]
- Threads [Strg + Alt + T]
- Module [Strg + Alt + M]
- Ereignisprotokoll [Strg + Alt + V]
- CPU [Strg + Alt + C]
- FPU [Strg + Alt + F]
- Fortgeschrittenes
- Mit Prozess verbinden
- Vom Programm trennen
- Parameter
- INT 3
- OutputDebugString
- SetDebugErrorLevel
- F12
- Desktop-Schnelleinstellung
- Den Debug-Desktop festlegen
- Compilerdirektiven: Message
- Assertions
- Optionen
- Debugger Optionen
- Projektoptionen
- Was ist Debugging?
Zitat:
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. - Brian W. Kernighan
Nein Spaß beiseite, für uns gilt: "Debugging ist das Auffinden, Diagnostizieren und Eliminieren von Fehlern in Software."
http://de.wikipedia.org/wiki/Debugging
- Der Debugger der Delphi IDE - Einführung
Wenn ein Programm mit F9 (bzw. "Menü -> Start -> Start" oder dem grünen Dreieck in der Toolbar) gestartet wird, läuft Delphi noch im Hintergrund. Tritt nun ein Fehler auf, schaltet sich der Debugger von Delphi ein. Delphi gibt dann eine Fehlermeldung aus und positioniert den Cursor in der Nähe des Fehlers im Quelltext.
z.B.
Delphi-Quellcode:
procedure TForm1.x;
begin
...
StrToInt('zwei');
...
end;
procedure TForm1.y;
begin
...
x;
x;
x;
...
end;
Delphi bringt eine Fehlermeldung: "Erste Zufalls-Exception bei $77E53887. Exception-Klasse EConvertError mit Meldung ''zwei' ist kein gültiger Integerwert'. Prozess Project1.exe (3500)"
Der Cursor ist entweder in der StrToInt Zeile (Zeile 4), oder wenn die Funktion abgebrochen wurde in der aufrufenden Funktion (Zeile 11).
Mit der Taste F8 (Gesamte Routine) kannst Du nun Schritt für Schritt das Programm debuggen.
Mit der Taste F9 (Start) kannst Du das Programm fortsetzen.
Willst Du das Programm an einer bestimmten Stelle debuggen (z.B. bevor ein Fehler auftritt), so kannst Du einen Haltepunkt (Breakpoint) setzen.
z.B.
Delphi-Quellcode:
procedure TForm1.x;
begin
...
StrToInt('zwei');
...
end;
procedure TForm1.y;
begin
...
x; <- Mit Cursor an diese Stelle gehen und F5 drücken
x;
x;
...
end;
Wenn Du in der Zeile 10 bist und die F5 Taste drückst, färbt sich diese Zeile rot und es erscheint ein roter Punkt davor.
Wird das Programm mit F9 ausgeführt, bleibt es an dieser Zeile stehen und springt in den Debugger (ohne Fehlermeldung)
Mit F9 kannst Du das Programm dann wieder fortsetzen.
Aber es gibt noch viel, viel mehr Möglichkeiten.
- Die möglichen Funktionen einzeln erklärt
Wenn Du Dich im Debug-Modus befindest, stehen Dir einige Befehle zur Verfügung:- Gesamte Routine [F8]
Führt ein Programm Zeile für Zeile aus. Prozeduren werden jedoch als eine Einheit ausgeführt.
z.B.
Delphi-Quellcode:
procedure TForm1.x;
begin
Caption := Caption + 'x';
end;
procedure TForm1.y;
begin
...
x; // <- hier steht der Cursor zum Debuggen vor F8
x; // <- und hier nach dem F8
x;
...
end;
Nach dem Drücken auf F8 wird die Procedure x; ausgeführt und der Cursor steht an der nächsten Anweisung x;
(Cursor springt von Zeile 8 nach Zeile 9)
- Einzelne Anweisung [F7]
Führt ein Programm Zeile für Zeile aus, auch Prozeduren werden Zeile für Zeile abgearbeitet.
z.B.
Delphi-Quellcode:
procedure TForm1.x;
begin // <- und hier nach dem F7
Caption := Caption + 'x';
end;
procedure TForm1.y;
begin
...
x; // <- hier steht der Cursor zum Debuggen vor dem F7
x;
x;
...
end;
Nach dem Drücken auf F7 wird in die Procedure x; gesprungen und der Cursor steht an dem begin.
(Cursor springt von Zeile 8 nach Zeile 2)
- Nächste Quelltextzeile [Umsch + F7]
Führt das Programm aus und hält an der nächsten ausführbaren Quelltextzeile.
Diese Funktion macht nur im CPU Fenster Sinn. Im "normalen" Quelltext ist die Funktion gleich dem F7 (Einzelne Anweisung)
Im CPU Fenster wird mit F7 und F8 je eine Asm Anweisung ausgeführt.
Mit Umsch + F7 dagegen jede Object Pascal Zeile als Block
- Zur Cursorposition gehen [F4]
Führt ein geladenes Programm bis zu der Stelle aus, an der sich der Cursor im Quelltext-Editor-Fenster befindet.
Das entspricht also einem temporären Haltepunkt (F5) an dieser Stelle und anschließendem Start des Programms (F9).
Nach dem Halten des Programms an der Stelle ist der Haltepunkt aber wieder entfernt.
(Der Haltepunkt ist auch wieder entfernt, wenn z.B. durch einen Fehler an einer anderen Stelle der Debugger aufgerufen wird.)
Nützlich ist das um einige Zeilen zu überspringen, von denen man weis dass sie keine Probleme verursachen.
- Ausführung bis Rückgabe [Umsch + F8]
Führt den Prozess solange aus, bis die Ausführung aus der aktuellen Funktion zurückkehrt.
So kannst Du sehr schnell die aktuelle Prozedur / Funktion ausführen und in die aufrufende Prozedur / Funktion springen.
(Wenn Du z.B. aus Versehen F7 statt F8 gedrückt hast)
- Ausführungsposition anzeigen
Positioniert den Cursor in einem Bearbeitungsfenster beim Ausführungspunkt.
Nützlich nach dem Durchstöbern von Code beim Debuggen, wenn Du nicht mehr genau weißt, wo der Debugger gerade ist
- Programm Pause [F12 im laufendem Programm]
Hält die Ausführung eines Programms vorübergehend an.
Das funktioniert natürlich nur, wenn der Debugger gerade nicht aktiv ist und das Programm läuft.
Es macht meist mehr Sinn einen Haltepunkt zu setzen. Delphi hält dann automatisch an der richtigen Stelle an.
Oft geht bei "Programm Pause" das CPU Fenster auf und zeigt den Asm Code der gerade ausgeführt wird.
Wenn Du nur Strg + F2 zum Programmende drücken willst ist das egal. (z.B. bei einer Endlosschleife)
- Programm zurücksetzen [Strg + F2]
Beendet den augenblicklichen Programmdurchlauf und gibt den entsprechenden Speicherplatz wieder frei.
Einfache Möglichkeit beim Debuggen das Programm zu beenden.
Leider wird nicht der ganze Speicherbereich wieder freigegeben. Es kann also durchaus passieren, dass nach einem halben Tag Debugging Delphi sehr viel Speicher belegt. Dann kannst Du Delphi einfach beenden und der Speicher ist wieder frei. Danach kann Delphi wieder gestartet werden und alles geht wieder.
- Untersuchen
Öffnet ein Inspektorfenster, in das Du den zu untersuchenden Eintrag eingeben kannst.
Es öffnet sich ein Dialog in den Du das zu untersuchende Objekt angeben kannst.
Danach wird ein "Debug Inspektor" geöffnet.
Der Debug Inspektor zeigt in 3 Kategorien alle Daten eines Objektes an.
(Die Daten können auch teilweise zur Laufzeit beim Debugging geändert werden.)- Daten: alle "privaten" Daten des Objektes
- Methoden: alle Methoden des Objektes (und von welchem Objekt die vererbte Methode genutzt wird.)
- Eigenschaften: alle Eigenschaften des Objektes (Wert, read=Variable/Funktion, write=Variable/Funktion)
- Auswerten/Ändern [Strg + F7]
Öffnet das Dialogfenster Auswerten/Ändern, in dem Du den Wert eines vorhandenen Ausdrucks auswerten oder ändern kannst.
Auswerten bedeutet sich anzeigen lassen welchen Wert Variablen / Objekte haben.
(Es ist sogar unter bestimmten Voraussetzungen möglich Funktionen auszuführen z.B. ShowMessage('blabla'))
- Ausdruck hinzufügen [Strg + F5]
Öffnet das Dialogfenster Darstellung überwachter Ausdrücke, in dem Du überwachte Ausdrücke erstellen und verändern kannst.
- Haltepunkt hinzufügen
Öffnet das Dialogfenster Haltepunkt bearbeiten, in dem Du Haltepunkte erstellen und verändern kannst.
-> Siehe Kapitel Haltepunkte
- Haltepunkte (Breakpoints)
Haltepunkte halten während einer Debug-Sitzung die Programmausführung an festgelegten Positionen an. Sie werden normalerweise vor potentiellen Problembereichen gesetzt. Wenn das Programm auf einen Haltepunkt trifft, wird es angehalten, und die Zeile oder die Speicheradresse mit dem Haltepunkt wird im Quelltext-Editor oder im Fenster CPU angezeigt. Du kannst dann mit dem Debugger den Status Deines Programms untersuchen und gesamte Routinen oder einzelne Anweisungen ausführen.
Es gibt im Wesentlichen 4 Arten von Haltepunkten:- Quelltexthaltepunkt
- Adresshaltepunkt
- Datenhaltepunkt
- Modulhaltepunkt
Alle Haltepunkte in Delphi haben einige Gemeinsamkeiten:- Per default halten die Haltepunkte das Programm an der gewünschten Stelle zum debuggen an.
(Daher auch der Name "Haltepunkte" )
- Es können auch andere Aktionen zugeordnet werden:
- Anhalten: hier stoppt der Debugger die Anwendung (s.o.)
- Spätere Exceptions ignorieren: der Debugger wird vorübergehend ausgeschaltet
- Spätere Exceptions behandeln: der Debugger wird wieder angeschaltet
- Meldung protollieren: schreibt Text in Ereignisprotokoll
- Eval-Ausdruck: wertet Ausdruck aus und schreibt ihn in das Ereignisprotokoll
- Gruppe aktivieren: aktiviert alle Haltepunkte der angegebenen Gruppe
- Gruppe deaktivieren: deaktiviert alle Haltepunkte der angegebenen Gruppe
- Haltepunkte können einer Gruppe zugeordnet werden, die dann aktiviert bzw. deaktiviert werden kann (s.o.)
- Haltepunkte können selbstverständlich auch einzeln aktiviert bzw. deaktiviert werden
- Haltepunkte können an eine Bedingung geknüpft werden
Die Aktion wird nur dann ausgeführt, wenn die Bedingung wahr ist
- Es kann ein Durchlaufzähler verwendet werden.
Die Aktion wird nur dann durchgeführt, wenn der Haltepunkt x mal "durchlaufen" wurde.
Quelltexthaltepunkte
So setzt Du einen Haltepunkt in einer Zeile Ihres Quelltextes:
Markiere im Quelltext-Editor die betreffende Zeile und führe eine der folgenden Aktionen durch:- Klicke auf den linken Rand der Zeile.
- Klicke an einer beliebigen Stelle der Zeile mit der rechten Maustaste und wähle Fehlersuche / Haltepunkt umschalten.
- Setze den Cursor an eine beliebige Position in der Zeile und drücke F5 (Standardtastenbelegung).
- Klicke mit der rechten Maustaste im Fenster Liste der Haltepunkte und wähle Hinzufügen / Quelltexthaltepunkt.
Haltepunkte werden farbig (standardmäßig rot) und mit einem Kreis am linken Rand des Quelltext-Editors dargestellt. Wenn Du den Mauszeiger über den Kreis bewegst, zeigt ein Kurzhinweis den Durchlaufzähler und die Bedingung des Haltepunkts an.
Wenn Dir die Nummer der Zeile bekannt ist, in der Du den Haltepunkt setzen willst, kannst Du so vorgehen:- Wähle Start / Haltepunkt hinzufügen / Quelltexthaltepunkt und gebe im entsprechenden Eingabefeld die Zeilennummer ein.
- Gebe im Dialogfenster Quelltexthaltepunkt hinzufügen die restlichen Informationen ein.
Wenn Du einen Haltepunkt setzt, wird die entsprechende Zeile hervorgehoben und mit einem Stop-Zeichen am Rand gekennzeichnet.
Ungültige Haltepunkte
Haltepunkte in nicht ausführbaren Quelltextzeilen (Kommentare, leere Zeilen, Deklarationen usw.) werden vom Debugger als ungültig betrachtet. Wenn Du einen ungültigen Haltepunkt setzt, markiert der Debugger den Haltepunkt als ungültig und hält nicht an. Lösche im Fenster Liste der Haltepunkte den ungültigen Haltepunkt. Du kannst ungültige Haltepunkte auch einfach ignorieren, da sie von der IDE bei der Ausführung des Programms deaktiviert werden.
Während der Link-Phase der Kompilierung markiert der Linker Codezeilen, die nicht zur Ausführung gelangen, als überflüssig. Der integrierte Debugger kennzeichnet Haltepunkte in solchem Code als ungültig.
Adresshaltepunkte
Der Debugger unterstützt Adresshaltepunkte. Er hält die Ausführung an, wenn die Anweisung an der angegebenen Adresse ausgeführt wird.
Um einen Adresshaltepunkt zu setzen, hast Du folgende Möglichkeiten:- Wähle im Fenster Liste der Haltepunkte Hinzufügen / Adresshaltepunkt. Gebe im Dialogfenster eine Adresse ein.
- Wähle im Menü Start den Befehl Haltepunkt hinzufügen / Adresshaltepunkt. Gebe im Dialogfenster eine Adresse ein.
- Klicke am linken Rand des CPU-Fensters mit der Maus.
- Klicke im CPU-Fenster unter Disassemblierung mit der rechten Maustaste und wähle Haltepunkt umschalten.
- Drücke F5.
Adresshaltepunkte sind nur verfügbar, wenn ein Prozess im Debugger angehalten wird.
Datenhaltepunkte
Der Debugger unterstützt Datenhaltepunkte. Diese Haltepunkte werden in Hardware-Debug-Registern gespeichert. Wenn ein Datenhaltepunkt gesetzt ist, unterbricht der Debugger die Programmausführung, wenn an der angegebenen Adresse Daten gespeichert werden.
Du hast drei Möglichkeiten, einen Datenhaltepunkt zu setzen:- Wähle im Fenster Liste der Haltepunkte den Befehl Hinzufügen / Datenhaltepunkt. Gebe im Dialogfenster eine Adresse und eine Länge ein. Du kannst auch Symbolnamen (z.*B. Variablennamen) eingeben.
- Wenn die Liste der überwachten Ausdrücke aktiv ist, markiere einen Eintrag und wähle im lokalen Menü Bei Änderung anhalten. Die Auswahl dieses Befehls setzt einen Haltepunkt zum Überwachen von Daten.
- Wähle im Menü Start den Befehl Haltepunkt hinzufügen / Datenhaltepunkt. Gebe im Dialogfenster eine Adresse und eine Länge ein.
Am Ende der aktuellen Debugger-Sitzung werden Datenhaltepunkte als ungültig markiert. Sie müssen beim Beginn der nächsten Sitzung wieder aktiviert werden (entweder im Fenster Liste der Haltepunkte oder im Fenster Überwachte Ausdrücke). Datenhaltepunkte sind nur verfügbar, wenn ein Prozess im Debugger angehalten wird.
- Die Debug Fenster
In der IDE können verschiedene Debug Fenster aufgerufen werden. (Menü -> Ansicht -> Debug Fenster -> ...)- Haltepunkte [Strg + Alt + B]
Zeigt das Fenster Liste der Haltepunkte an.
(Siehe auch Kapitel Haltepunkte.)
- Aufruf-Stack [Strg + Alt + S]
Zeigt das Fenster Aufruf-Stack an.
Der Aufruf Stack ist eines der nützlichsten Werkzeuge des Debuggers.
Wenn ein Fehler in einer Funktion auftritt, fragt man sich manchmal: "Von wo wurde diese Prozedur aufgerufen und warum mit diesen Parametern?"
Ein Blick in den Aufruf Stack bringt Klarheit.
z.B.
Delphi-Quellcode:
...
procedure TForm1.FormCreate(Sender: TObject);
begin
x;
end;
procedure TForm1.x;
begin
y('zwei');
end;
procedure TForm1.y(s: string);
begin
z(s);
end;
procedure TForm1.z(s: string);
var
i: Integer;
begin
for i := 1 to Length(s) do
begin
Assert(s[i] in ['0', '1'..'9', ',', '.'], 'Ups, ungültige Zeichen in String enthalten.');
end;
Tag := StrToInt(s);
end;
end.
Der Debugger bleibt in z an dem Assert stehen -> Fehler:
Erste Zufalls-Exception bei $77E53887. Exception-Klasse EAssertionFailed mit Meldung 'Ups, ungültige Zeichen in String enthalten. (C:\TEMP\Unit1.pas, Zeile 23)'. Prozess Project1.exe (3256)
Im Aufrufstack siehst Du nun:- TForm1.z('zwei')
- TForm1.y('zwei')
- TForm1.x
- TForm1.FormCreate(???)
- Project1
Wenn Du nun auf TForm1.y('zwei') doppelklickst, springt der Cursor in die Zeile nach dem Aufruf von z (also dem end in Zeile 15).
Wenn Du nun auf TForm1.x doppelklickst, springt der Cursor in die Zeile nach dem Aufruf von y (also dem end in Zeile 10).
Das gleiche gilt auch für FormCreate.
Project1 ist die Projektdatei (*.dpr) Hier steht der Cursor dann beim Application.Run (bzw. dem end danach)
- Überwachte Ausdrücke [Strg + Alt + W]
Zeigt das Fenster Liste überwachter Ausdrücke an.
Diese Liste zeigt den aktuellen Wert des überwachten Ausdrucks basierend auf dem Sichtbarkeitsbereich der Ausführungspunkt an. Die Liste überwachter Ausdrücke besteht aus mehreren Registerseiten, wobei jede Seite eine bestimmte Gruppe von Ausdrücken enthält. Es kann jeweils nur eine Gruppe überwacht werden (die auf der aktiven Seite der Liste), und nur diese Gruppe wird beim Debugging berücksichtigt. Durch das Gruppieren von Ausdrücken kannst Du verhindern, dass bereichsüberschreitende Ausdrücke die Überwachung verlangsamen.
In der Liste wird die Prozess- und/oder Thread-ID des anzuzeigenden Prozesses bzw. Threads aufgeführt. Die Prozess-ID ist nur zu sehen, wenn mehrere Prozesse in den Debugger geladen werden. Die Thread-ID wird nur angezeigt, wenn der betreffende Prozess mehrere Threads enthält.
Die linke Seite der Liste zeigt die als Überwachungen eingegebenen Ausdrücke. Die zugehörigen Datentypen und Werte sind rechts zu sehen. Die Werte zusammengesetzter Datenobjekte (z.B. Arrays und Strukturen) stehen in geschweiften Klammern { }.
Die Liste überwachter Ausdrücke ist leer, wenn Du keine überwachten Ausdrücke eingefügt hast.
Wenn sich die Ausführungspunkt an eine Stelle bewegt, an der eine der Variablen im Ausdruck undefiniert ist (außerhalb des Sichtbarkeitsbereiches), wird der gesamte überwachte Ausdruck undefiniert. Erreicht die Ausführungsposition wieder eine Stelle, an welcher der überwachte Ausdruck ausgewertet werden kann (wenn also die Ausführungsposition wieder in den Sichtbarkeitsbereich des Ausdrucks eintritt), so zeigt die Liste überwachter Ausdrücke wieder den aktuellen Wert des Ausdrucks an.
Hinweis: Wenn es sich bei dem überwachten Ausdruck um ein Element eines varianten Arrays handelt, muss die Option Funktionsaufrufe gestatten aktiviert sein. Nehmen wir an, in Deinem Programm gibt es ein variantes Array namens A, und Du willst A[0] überwachen. Wenn im Dialogfenster Darstellung überwachter Ausdrücke die Option Funktionsaufrufe gestatten nicht aktiviert ist, wird der Wert von A[0] als Nicht verfügbarer Wert angezeigt.
- Lokale Variablen [Strg + Alt + L]
Zeigt die lokalen Variablen der Funktion im Debugging-Modus an.
Eigentlich dasselbe wie "Überwachte Ausdrücke", nur das hier schon automatisch die lokalen Variablen zu sehen sind.
(Und das sind ja in der Regel die Interessanten. )
- Threads [Strg + Alt + T]
Zeigt das Fenster Thread-Status an.
Verwende dieses Fenster zum Anzeigen des Status aller Prozesse und Threads, die aktuell in der im Debugger geladenen Anwendung ausgeführt werden.
Fenster Thread-Status- Thread-ID: Zeigt vom BS zugewiesene Thread-ID, Prozessname und ob der Thread benannt ist (der Name wird hier ebenfalls angezeigt).
- Zustand: Der Thread-Status lautet entweder Ausführbar, Angehalten, Blockiert oder Keiner. Bei einem Prozess wird angezeigt, wie dieser erzeugt wurde: Abgespalten, Angehängt oder Prozessübergreifend angehängt.
- Verzeichnis: Zeigt die Position im Quelltext an. Zeigt die Adresse an, falls keine Quelltextposition verfügbar ist. Bei einem Remote-Prozess wird der Name des entfernten Rechners angezeigt.
- Status: Der Thread-Status zeigt eines der folgenden Elemente an:[list:6ab28500a7]
- Haltepunkt: Der Thread wurde aufgrund eines Haltepunkts angehalten.
- Fehler: Der Thread wurde aufgrund einer Prozessor-Exception angehalten.
- Unbekannt: Der Thread ist nicht der aktuelle Thread, sodass sein Status unbekannt ist.
- Schrittweise ausgeführt: Der letzte Einzelschrittbefehl wurde erfolgreich abgeschlossen.
Threads und das Debugging mehrerer Prozesse
Die im Fenster Thread-Status angezeigten Threads können im selben oder in verschiedenen Prozessen ausgeführt werden. Der erste geladene Prozess steht am Anfang der Liste, die weiteren Prozesse darunter. Beendete Prozesse werden aus der Liste entfernt. Für jeden Prozess können ein oder mehrere zugehörige Threads vorhanden sein, die in der Liste direkt unter dem jeweiligen Prozess angezeigt werden. Der Haupt-Thread steht direkt unter dem zugehörigen Prozess, neue Threads, die vom Prozess erstellt werden, werden zur Liste der Threads dieses Prozesses hinzugefügt. Beendete Threads werden aus der Liste entfernt.
Unter dem aktuellen Prozess und dem aktuellen Thread sind diejenigen zu verstehen, die den Kontext für die nächste Benutzeraktion bilden (Start, Pause, Zurücksetzen usw.). In den meisten Debugger-Ansichten sind ferner relevante Informationen zum aktuellen Prozess und Thread zu sehen. Der aktuelle Prozess wird durch ein grünes Pfeilsymbol gekennzeichnet. Nicht-aktuelle Prozesse sind an einem hellblauen Pfeil zu erkennen.
Du kannst einen anderen Prozess als aktuellen Prozess wählen, indem Du einen nichtaktuellen Prozess oder Thread auswählst und dann im Popup-Menü Aktuell wählst. Wenn dies für einen Prozess geschieht, wird dieser zusammen mit seinem derzeitigen Thread aktuell. Wenn die Option für einen Thread gewählt wird, der nicht zum aktuellen Prozess gehört, wird der zum Thread gehörende Prozess aktuell.
Bei einem Debugging-Ereignis (Haltepunkt, Exception, angehalten) zeigt die Thread-Ansicht den Status der einzelnen Threads an. Mithilfe des Kontextmenüs kannst Du einen anderen Thread oder Prozess aktuell machen. Wenn ein Thread als aktuell markiert ist, wird die nächste Operation relativ zu diesem ausgeführt.
- Module [Strg + Alt + M]
Zeigt das Fenster Module an.
Das Fenster Module zeigt eine Liste aller vom Debugger gesteuerten Prozesse sowie eine Liste der Module, die aktuell von den einzelnen Prozessen geladen wurden. Der erste geladene Prozess steht am Anfang der Liste, die weiteren Prozesse darunter. Beendete Prozesse werden aus der Liste entfernt. Für jeden Prozess können ein oder mehrere Module vorhanden sein, die vom Prozess geladen werden. Die Module werden in der Liste direkt unter dem jeweiligen Prozess angezeigt. Das von einem Prozess zuerst geladene Modul wird direkt unter diesem angezeigt, weitere Module darunter. Aus dem Speicher freigegebene Module werden aus der Liste entfernt.
Der aktuelle Prozess wird durch ein grünes Pfeilsymbol gekennzeichnet. Nichtaktuelle Prozesse weisen keine Markierung auf.
Haltepunkte zum Laden von Modulen sind nicht prozessspezifisch und werden von jedem Prozess gefunden, der ein Modul lädt, für das ein Haltepunkt definiert wurde.
Verwende die Kontextmenüs im Fenster Module, um Module zu diesem hinzuzufügen, die Programmausführung anzuhalten, wenn ein Modul geladen wird, zum Navigieren zu Eintrittspunkten oder zum Anzeigen des Quelltexts eines Moduls im Quelltext-Editor.
- Ereignisprotokoll [Strg + Alt + V]
Zeigt das Fenster mit dem Ereignisprotokoll an.
Das Ereignisprotokoll zeigt Prozessbotschaften, Haltepunktbotschaften, OutputDebugString-Botschaften und Fensterbotschaften an. Wenn Du mit der rechten Maustaste auf diese Registerkarte klickst, wird ein Kontextmenü angezeigt, mit dessen Optionen das Ereignisprotokoll gelöscht, in einer Textdatei gespeichert, Kommentare hinzugefügt und Optionen für das Ereignisprotokoll festgelegt werden können.
- CPU [Strg + Alt + C]
Zeigt das CPU-Fenster an.
Das CPU-Fenster besteht aus fünf voneinander getrennten Bereichen. Jeder Ausschnitt gibt Dir einen Einblick in einen bestimmten maschinennahen Aspekt Ihrer laufenden Anwendung.- Disassemblierungsausschnitt: zeigt Assembler-Anweisungen an, die aus der Maschinensprache Ihrer Anwendung disassembliert wurden. Außerdem zeigt der Disassemblierungsausschnitt den Originalquelltext des Programms oberhalb der zugehörigen Assembler-Anweisungen an.
- Speicherauszugsausschnitt: zeigt einen Speicherauszug eines beliebigen, für das momentan geladene ausführbare Modul zugänglichen, Speicherbereichs an. Per Vorgabe wird der Speicherinhalt in hexadezimalen Bytes angezeigt.
- Maschinen-Stack-Ausschnitt: zeigt den gegenwärtigen Inhalt des Programm-Stacks an. Per Vorgabe wird der Stack in hexadezimalen Long- (32 Bit-) Werten angezeigt.
- CPU-Registerausschnitt: zeigt die aktuellen Werte der CPU-Register an.
- Flags-Ausschnitt: zeigt die momentanen Werte der CPU-Flags an.
- FPU [Strg + Alt + F]
Zeigt das FPU-Fenster an.
Mithilfe des FPU-Fensters kannst Du den Inhalt der Gleitkommeinheit des Prozessors anzeigen. Du kannst hier Gleitkomma- oder MMX-Informationen überprüfen (MMX ist eine Erweiterung des Pentium-Prozessors von Intel mit zusätzlichen Befehlen für Multimedia-Operationen und einer verbesserten internen Architektur, die eine höhere Ausführungsgeschwindigkeit ermöglicht).
Im FPU-Fenster werden die Werte der Register sowie die Status-, Kontroll- und Tag-Wörter der FPU angezeigt. Das Fenster besteht aus drei Bereichen:- FPU-Register: ist der größte Bereich und enthält den Register-Stack der Gleitkommaeinheit.
- Kontroll-Flags enthält die Flags des Kontrollwortes der FPU.
- Status-Flags enthält die Flags des Statusworts der FPU.
Oberhalb des Registerbereichs befindet sich ein Feld mit der Adresse des Befehlszeigers, dem Opcode und dem Operanden der zuletzt ausgeführten FPU-Anweisung.
Hinweis: Das FPU-Fenster ist in eventuell nicht in allen Programmversionen verfügbar.
[*] Fortgeschrittenes- Mit Prozess verbinden
(Menü -> Start -> Mit Prozess verbinden...)
Zeigt eine Liste der gegenwärtig laufenden Prozesse an, die Du mit dem Debugger untersuchen kannst.
Es ist also durchaus möglich z.B. notepad.exe (von Microsoft) mit Delphi in der CPU Ansicht zu debuggen.
- Vom Programm trennen
(Menü -> Start -> Von Programm trennen)
Hält den Debug-Vorgang eines Prozesses an.
Das ist das Gegenstück zum "Dem Prozess beifügen".
- Parameter
(Menü -> Start -> Parameter...)
Ruft ein Dialogfenster zur Angabe der Startparameter einer Anwendung, einer ausführbaren Host-Datei für die zu testenden gemeinsamen Objekte. Hier kann auch ein Computer für die externe Fehlersuche angegeben werden.
- INT 3
Der Interupt 3 bringt das Programm zum stehen und ruft den Debugger auf.
Das funktioniert natürlich nur, wenn auch ein Debugger läuft.
Sonst gibt es eine Fehlermeldung (Allgemeine Schutzverletzung)
Wenn Du also an einer bestimmten Stelle im Programm anhalten möchtest und (warum auch immer) keinen Haltepunkt verwenden kannst bringst Du Deine Applikation mit folgendem Quelltext zu stehen:
Alternativ kannst Du auch DebugBreak, die passende API Funktion von Windows verwenden.
Leider öffnet sich aber bei DebugBreak das CPU Fenster und Du musst noch einmal F8 drücken um wieder an der "richtigen" Stelle im Code zu sein.
- OutputDebugString
Mit dieser API Funktion (kernel32.dll) wird beim Debuggen ein Eintrag in das Ereignisprotokoll (s.o.) geschrieben.
procedure OutputDebugString(lpOutputString: PChar); stdcall;
Es ist also eine einfache Möglichkeit Informationen auszugeben, ohne Messageboxen zu benutzen.
OutputDebugString('Test');
Aber wenn OutputDebugString auch in der "Endbenutzerversion" verwendet wird, solltest Du wissen, dass das keine Delphi Funktion ist, sondern ein API Aufruf.
Wenn die Applikation nicht in einem Debugger läuft, werden diese Informationen an den Systemdebugger weitergereicht. Wenn der Systemdebugger nicht aktiv ist, geschieht nichts.
Aber wer möchte schon, dass ein "Fremder" sein Programm debuggt?
- SetDebugErrorLevel
Die API Funktion (kernel32.dll) setzt die minimale Fehlerstufe, welche Windows veranlasst Debugging Ereignisse zu erstellen und an den Debugger weiterzugeben.
procedure SetDebugErrorLevel(dwLevel: DWORD); stdcall;
Folgende Werte können an dwLevel übergeben werden:- 0:
Es werden keine Fehler gemeldet. Das ist die Default Einstellung
- SLE_ERROR = 1:
reicht nur ERROR Level Debugging Ereignisse weiter
- SLE_MINORERROR = 2:
reicht MINORERROR und ERROR Level Debugging Ereignisse weiter
- SLE_WARNING = 3:
reicht WARNING, MINORERROR und ERROR Level Ereignisse weiter
Auch wenn eine niedrige Fehlerstufe eingestellt ist, kann der aufgetretene Fehler mit GetLastError ermittelt werden.
- F12
Während der Ausführung der Applikation wird der Debugger hervorgeholt und zum aktuellen ASM-Befehl in der CPU-Ansicht geschalten. (Siehe oben bei Pause.)
- Desktop-Schnelleinstellung
Die Symbolleiste Desktops enthält standardmäßig folgende Schaltflächen:- Auswahlliste
Eine Liste der gespeicherten Desktop-Layouts. Wähle hier das gewünschte Layout.
- Aktuellen Desktop speichern
Das Dialogfenster Desktop speichern wird geöffnet, in dem Du die aktuellen Desktop-Einstellungen unter einem bestimmten Namen speichern kannst.
- Debug-Desktop einstellen
Das aktuelle Layout wird als Debug-Desktop verwendet, der zur Laufzeit automatisch angezeigt wird.
Du kannst mit den entsprechenden Menübefehlen die aktuellen Desktop-Einstellungen speichern (Ansicht / Desktops / Desktop speichern), nicht mehr benötigte Layouts löschen (Ansicht / Desktops / Löschen) und ein bestimmtes Layout als Debug-Desktop einrichten (Ansicht / Desktops / Debug-Desktop einstellen).
Du kannst die Desktop-Einstellungen anpassen und anschließend speichern. Mithilfe der Desktops-Symbolleiste in der IDE kannst Du dann jederzeit zwischen den gespeicherten Desktop-Layouts wechseln.
So passt Du ein Desktop-Layout an und speicherst die Einstellungen:- Ordne die Bildschirmelemente Deinen Wünschen entsprechend auf dem Desktop an.
- Klicke in der Symbolleiste Desktops auf die Schaltfläche Aktuellen Desktop speichern (Du kannst auch den Befehl Ansicht / Desktops / Desktop speichern wählen).
- Gebe einen Namen für das neue Layout ein, und bestätige ihn mit OK.
Du kannst den Namen eines neuen oder vorhandenen Desktops direkt in das Kombinationsfeld der Desktops-Symbolleiste eingeben und die Eingabetaste drücken. Bei einem neuen Desktop wird das aktuelle Layout unter diesem Namen gespeichert. Wenn Du den Namen eines vorhandenen Layouts eingibst, wird der Desktop anschließend angezeigt.
Das gewählte Layout bleibt anschließend für alle Projekte in Kraft und wird auch beim nächsten Starten verwendet.
Du kannst beliebig viele Layouts erstellen. Die Namen werden in die Auswahlliste der Symbolleiste Desktops und in das Untermenü Ansicht / Desktops aufgenommen. Wähle hier einfach den gewünschten Eintrag aus, um zu dem betreffenden Desktop zu wechseln.
Es empfiehlt sich, ein bestimmtes Layout für Debugging-Sitzungen festzulegen.
- Den Debug-Desktop festlegen
Du kannst einen der gespeicherten Desktops als das Layout festlegen, das jedes Mal automatisch verwendet wird, wenn Du eine Anwendung startest. Dies ist besonders beim Debuggen von Programmen hilfreich, da dann die benötigten Fenster (z.B. Überwachte Ausdrücke oder Haltepunkte) bereits an der gewünschten Position geöffnet sind.
Hinweis: Nach dem Beenden der Debugging-Sitzung wird der vorher verwendete Desktop wiederhergestellt.
So legst Du den Debug-Desktop fest:- Ordne die Bildschirmelemente Deinen Wünschen entsprechend auf dem Desktop an.
- Klicke in der Symbolleiste Desktops auf die Schaltfläche Debug-Desktop einstellen (Du kannst auch den Befehl Ansicht/Desktops/Debug-Desktop einstellen wählen).
- Wähle das gewünschte Layout.
Der Debug-Desktop wird dann zur Laufzeit einer Anwendung angezeigt. Ansonsten wird das Desktop-Layout verwendet, das Du in der Symbolleiste Desktops auswählst.
- Compilerdirektiven: Message
Syntax {$MESSAGE HINT|WARN|ERROR|FATAL 'Textstring' }
Diese Direktive ermöglicht dem Quelltext, wie der Compiler Hinweise, Warnungen und Fehlermeldungen zu generieren. Sie ähnelt den Anweisungen #emit und pragma warn in C/C++.
Der Meldungstyp (HINT, WARN, ERROR oder FATAL) ist optional. Ohne diese Angabe wird HINT verwendet. Der Textstring muss angegeben und in einfache Anführungszeichen eingeschlossen werden.
z.B.
Delphi-Quellcode:
{$MESSAGE 'Boo!'} // Hinweis
{$Message Hint 'Füttere die Katzen'} // Hinweis
{$messaGe Warn 'Sieht nach Regen aus.'} // Warnung
{$Message Error 'Nicht implementiert'} // Fehler, die Kompilierung wird fortgesetzt
{$Message Fatal 'Bang. Tot.'} // Fehler, die Kompilierung wird abgebrochen
- Assertions
Die Prozedur Assert prüft, ob ein Boolescher Ausdruck wahr ist, gibt eine Fehlermeldung aus (und beendet das Programm mit einem Laufzeitfehler, falls die Unit SysUtils nicht eingebunden ist).
procedure Assert(expr : Boolean [; const msg: string]);
In Delphi kannst Du mit Assert testen, ob Bedinungen verletzt werden, die als zutreffend angenommen werden. Assert bietet eine Möglichkeit, eine unerwartete Bedingung zu simulieren und ein Programm anzuhalten, anstatt die Ausführung in unbekannter Konstellation fortzusetzen.
Assert übernimmt als Parameter einen Booleschen Ausdruck und einen optionalen Meldungstext. Schlägt der Boolesche Test fehl, löst Assert eine EAssertionFailed-Exception aus. Wenn ein Meldungstext übergeben wurde, wird das Exception-Objekt mit diesem String erzeugt. Andernfalls wird ein Standardtext angezeigt. Zusätzlich wird der Dateipfad, der Dateiname und die Zeilennummer angegeben, in der Assert fehlgeschlagen ist.
Die Unit SysUtils wandelt Laufzeitfehler in Exceptions um. Wenn SysUtils allerdings nicht in die Anwendung eingebunden ist, wird der Laufzeitfehler 227 ausgegeben und keine EAssertionFailed-Exception ausgelöst. Dieser Laufzeitfehler hält das Programm an.
Hinweis: Die Unit SysUtils wird in den meisten VCL-Anwendungen auch dann verwendet, wenn sie nicht explizit der uses-Klausel hinzugefügt wurde. Beispielsweise wird durch die Verwendung der Unit Forms auch die Unit SysUtils einbezogen, weil die Unit Forms SysUtils verwendet
In der Regel werden Assertions nicht in Programmversionen verwendet, die zur Auslieferung vorgesehen sind. Deshalb wurden Compiler-Direktiven implementiert, mit denen die Generierung des zugehörigen Codes deaktiviert werden kann:
(Siehe auch weiter unten in "Optionen".)
Delphi-Quellcode:
$ASSERTIONS ON/OFF (Lange Form)
$C +/- (Kurze Form)
Es handelt sich dabei um globale Optionen, die sich unabhängig von Deiner Position auf die ganze Quelltextdatei auswirken. Der kleinste Gültigkeitsbereich für Assertions ist eine Quelltextdatei. Assertions sind standardmäßig deaktiviert.
[*] Optionen
Hier stehen sie Auswirkungen der Einzelnen Optionen auf den Debugger... - Debugger Optionen
Die Optionen des Delphi Debuggers finden sich in "Menü -> Tools -> Debugger-Optionen...".
Der Dialog untergliedert sich in 4 Bereiche:- Allgemein
Hier werden die Allgemeinen Einstellungen festgelegt.
Manchmal ist es recht praktisch, wenn das Popup Menü des Editors beim Debuggen die zum Debugging relevanten Menüpunkte oben anzeigt. Die Option "Beim Start Debugger-Menü nach oben" erledigt dies.
Der wichtigste Punkt dürfte aber "Integrierter Debugger" sein. Damit kannst Du den Debugger komplett ausschalten. Der Debugger stoppt dann auch nicht an Haltepunkten.
- Ereignisprotokoll
Über die Registerkarte Ereignisprotokoll des Dialogfensters Debugger-Optionen kannst Du die Optionen für Ereignisprotokolle einstellen. Über diese Optionen kannst Du festlegen, wie viele Meldungen ausgegeben und wie viele Ereignisse angezeigt werden sollen.
- Sprach-Exceptions
Über die Registerkarte Sprach-Exceptions im Dialogfenster Debugger-Optionen kannst Du konfigurieren, wie der Debugger Sprach-Exceptions behandelt, wenn diese vom getesteten Programm ausgelöst werden.- Folgende Exception-Typen ignorieren
Hier werden die Exception-Typen aufgeführt, die während des Testens vom Debugger ignoriert werden sollen. Markierte Typen werden ignoriert, nicht markierte werden berücksichtigt.
Der Debugger unterbricht die Programmausführung nicht, wenn die ausgelöste Exception im Listenfeld aufgeführt und markiert ist. Dasselbe gilt für Exceptions, die von einer im Listenfeld aufgeführten (und dort markierten) Exception abgeleitet sind. Mit den Schaltflächen Hinzufügen und Entfernen kannst Du Exception-Typen zur Liste hinzufügen oder daraus entfernen. Wenn z.B. im Listenfeld der Typ EMathError enthalten und markiert ist und das Programm eine EMathError-Exception auslöst, wird die Programmausführung nicht unterbrochen. Auch beim Auslösen der Exception EOverflow hält der Debugger nicht an, weil EOverflow von EMathError abgeleitet ist.
- Bei Delphi-Exceptions stoppen
Aktiviere dieses Kontrollkästchen, wenn der Debugger die Programmausführung anhalten soll, sobald eine Delphi-Exception ausgelöst wird. Standardmäßig ist diese Option aktiviert. In diesem Fall kannst Du den Debugger anweisen, spezielle Exception-Typen zu ignorieren, indem Du diese im Listenfeld "Folgende Exception-Typen ignorieren" angibst. Diese Einstellung ist standardmäßig aktiviert.
- BS-Exceptions
In der Liste des Bildlauffeldes Exceptions sind Exceptions aufgeführt. In den Feldern darunter kannst Du festlegen, wie diese behandelt werden sollen. Zum Ändern der Optionen markiere die betreffende Exception und stelle die Optionen Behandelt von und Beim Fortsetzen wie gewünscht ein.
- Projektoptionen
In den Projektoptionen ("Menü -> Projekt -> Optionen...") kannst Du die projektbezogenen Einstellungen vornehmen.
Diese Einstellungen werden dann in der Projektname.dof gespeichert (dof = Delphi Option File).
Wenn die Anwendung kompiliert wird werden die Einstellungen auch in der Projektname.cfg Datei gespeichert.
Die *.cfg Datei wird auch vom Komandozeilen Compiler verwendet. (Dazu habe ich folgendes Tutorial geschrieben: Anleitung zum Kommandozeilen Compiler (dcc32.exe))
Aber nun die für das Debugging relevanten Optionen:- Compiler
- Debug-Informationen
Debugging-Informationen werden in die Unit-Dateien (.dcu oder .dpu) aufgenommen. Diese Option entspricht dem Schalter {$D}.
Mit der Direktive $D kann die Generierung von Debug-Informationen aktiviert und deaktiviert werden. Diese Informationen beinhalten für jede Prozedur eine Tabelle mit Zeilennummern, in der Adressen des Objektcodes als Zeilennummern im Quelltext dargestellt werden.
Bei Units werden die Debug-Informationen in der Unit-Datei gemeinsam mit dem Objektcode der Unit aufgezeichnet. Durch die Debug-Informationen erhöht sich die Größe der Unit-Datei. Das Kompilieren von Programmen, die diese Unit verwenden, erfordert deshalb mehr Speicher. Die Größe und die Ausführungsgeschwindigkeit des ausführbaren Programms werden aber nicht nachteilig beeinflusst.
Wenn ein Programm oder eine Unit im Status {$D+} kompiliert wird, kannst Du das betreffende Modul mit dem integrierten Debugger in Einzelschritten testen und Haltepunkte setzen.
Mit den Optionen Mit Debug-Infos und Map-Datei (auf der Registerkarte Linker des Dialogfelds Projektoptionen) können nur vollständige Zeileninformationen für Module erzeugt werden, die im Status {$D+} kompiliert wurden.
- Lokale Symbole
Lokale Symbolinformationen werden generiert. Diese Option entspricht dem Schalter {$L}..
Mit der Schalter-Direktive $L kann die Generierung der lokalen Symbolinformationen aktiviert und deaktiviert werden. Die lokalen Symbolinformationen sind die Namen und Typen aller lokalen Variablen und Konstanten eines Moduls, also die Symbole im implementation-Abschnitt des Moduls und in seinen Prozeduren und Funktionen.
Bei Units werden die lokalen Symbolinformationen zusammen mit dem Objektcode in der Unit-Datei gespeichert. Lokale Symbolinformationen vergrößern eine Unit-Datei. Das Kompilieren von Programmen, die diese Unit verwenden, erfordert also mehr Speicher. Die Größe und die Ausführungsgeschwindigkeit der Programme werden aber nicht nachteilig beeinflusst.
Wenn ein Programm oder eine Unit im Status {$L+} kompiliert wird, kannst Du die lokalen Variablen des Moduls im integrierten Debugger überprüfen und ändern. Außerdem können die Aufrufe von Prozeduren und Funktionen des Moduls über die Option Ansicht/Aufruf-Stack überprüft werden.
Mit den Optionen Mit TD32-Debug-Info und Map-Datei auf der Registerkarte Linker des Dialogfelds Projekt/Optionen können für ein Modul nur dann lokale Symbolinformationen erzeugt werden, wenn es im Status {$L+} kompiliert wurde.
Der Schalter $L wird normalerweise zusammen mit dem Schalter $D eingesetzt, der die Erzeugung von Tabellen mit Zeilennummern zu Testzwecken steuert. Im Status {$D-} wird die Direktive $L ignoriert.
- Referenzinfo/Nur Definitionen
Für den Quelltext-Browser, den Code-Explorer und den Projekt-Browser werden Informationen zu Symbolreferenzen generiert. Diese Option entspricht dem Schalter {$Y}. Wenn beide Optionen aktiviert sind (
{$YD}), erzeugt der Compiler Informationen darüber, wo die Bezeichner definiert sind. Ist Referenzinfo aktiviert, aber Nur Definitionen deaktiviert ({$Y+}), werden Informationen generiert, wo die Bezeichner definiert und verwendet werden. Diese Optionen sind nur wirksam, wenn Debug-Informationen und Lokale Symbole (siehe oben) aktiviert werden.
- Assertion
Anweisungen für Assertions (Annahmen) werden in den Quelltext aufgenommen. Diese Option entspricht dem Schalter {$C}. Im Gegensatz zu Exceptions können Assertions aus einem für die Weitergabe bestimmten Programm entfernt werden. Erstelle nach dem Deaktivieren dieser Option die Codebase, um die Anweisungen zu entfernen.
Assertions wurden auch weiter oben bei "Fortgeschrittenes" beschrieben.
- Mit Debug-DCUs
Die Debug-Versionen der VCL werden in die Anwendung gelinkt. Die DCU-Dateien enthalten Debugging-Informationen und sind mit Stack-Rahmen kompiliert. Ist diese Option aktiviert, fügt der Compiler automatisch den Debug-DCU-Pfad (Registerkarte Allgemein von Tools/Debugger-Optionen) am Anfang des Suchpfades auf der Registerkarte Verzeichnisse/Bedingungen des Dialogfensters Projektoptionen ein.
- Linker
- Mit TD32 Debug-Info
In die ausführbare Datei werden Debugging-Informationen aufgenommen. Die ausführbare Datei wird dadurch zwar größer, jedoch wirkt sich dies nicht auf Speicherbedarf oder Geschwindigkeit aus.
Aktiviere diese Option nur, wenn Du einen externen Debugger verwendest, da sich die Kompilierzeit des Programms verlängert.
- Mit ext. Debug-Smbolen
Aktiviere diese Option, wenn Du Remote-Debugging verwendest.
[/list :6ab28500a7]
That's it.
Ich hoffe Du kannst die Informationen in diesem Tutorial verwenden um noch bessere Programme zu erstellen.
Viel Spaß
(°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
|