close

Anmelden

Neues Passwort anfordern?

Anmeldung mit OpenID

Ausgewählte Kapitel des Software Engineering Betriebssystem

EinbettenHerunterladen
Seminar SS 2005
Ausgewählte Kapitel des Software Engineering
durchgeführt am
Institut für Wirtschaftsinformatik – Software Engineering
der Johannes Kepler Universität Linz
Altenberger Str. 69, A-4040 Linz, Austria
Tel: +43-70-2468-9435
Fax: +43-70-2468-9430
Email: johannes.sametinger@jku.at
Leitung: a. Univ.-Prof. Dr. Johannes Sametiner
Betriebssystem Debugging Support und wie Win32
Debuggers arbeiten
Erweitertes Debuggen mit Visual Studio .NET
Debugging 2
Ingo Baumann
ingo.baumann@students.jku.at
Datum der Präsentation 02.06.2005
Debugging 2
2
Inhaltsverzeichnis
Kurzfassung.................................................................................................................. 3
1
2
Einleitung................................................................................................... 3
Typen von Windows Debuggern............................................................... 4
2.1
2.2
User-Mode Debugger ........................................................................... 4
Kernel-Mode Debuggers ...................................................................... 4
2.2.1
2.2.2
Kernel Debugger (KD) ......................................................................... 4
WinDBG............................................................................................... 4
2.2.3
2.3
SoftICE ................................................................................................. 5
Windows Betriebssystemunterstützung für Debuggees ....................... 5
2.3.1
2.3.2
Just-In-Time (JIT) Debugging.............................................................. 5
Automatisch in einem Debugger starten (Image File Execution
Options) ................................................................................................ 6
Ein einfacher Win32 Debugger ................................................................. 6
3
4
4.1
Besonderheiten beim Debugging............................................................... 7
Speicher lesen und schreiben................................................................ 7
4.2
4.3
Haltepunkte und Single Stepping ......................................................... 7
Symbol Tables, Symbol Engines and Stack Walking .......................... 8
4.3.1
4.3.2
Verschiedene Symbolformate............................................................... 8
Symbolinformation abrufen.................................................................. 9
4.3.3
4.4
Walking the Stack............................................................................... 10
Step Into, Step Over und Step Out ..................................................... 10
5
5.1
Erweitertes debuggen mit Visual Studio .NET ....................................... 11
Erweitete Haltepunkte ........................................................................ 11
5.1.1
5.1.2
IntelliSense ......................................................................................... 12
Modifizieren von vor Ort Haltepunkten (location breakpoints)......... 12
5.1.3
5.2
Mehrere Haltepunkte in einer Zeile.................................................... 13
Das Beobachtungsfenster (watch window) ........................................ 13
6
7
Zusammenfassung ................................................................................... 13
Literaturverzeichnis ................................................................................. 14
8
Abbildungsverzeichnis ............................................................................ 14
Debugging 2
3
Kurzfassung
Anhand dieser Seminararbeit zeige ich die Unterschiede zwischen den verschiedenen Windows
Debuggern auf. Dabei gibt es auf der einen Seite die User-Mode Debugger und auf der Anderen die
Kernel-Mode Debugger. Hybride Debugger sind Jene, mit denen in beiden Modi gearbeitete werden
kann. In diesem Kapitel werden mehrere Debugger vorgestellt, deren Arbeitsweise erklärt und die
Unterschiede zwischen den Debuggern aufgezeigt.
Die Gründe zur Notwendigkeit von Just-In-Time Debugging und das automatische Starten in einem
Debugger werden im Abschnitt Windows Betriebssystemunterstützung für Debuggees behandelt.
Anschließend zeigt ein Pseudocodebeispiel wie wenig Aufwand nötig ist, um einen minimalen Win32
Debugger zu erzeugen.
Unter Besonderheiten beim Debuggen versteht man das Lesen und Schreiben des Speichers vom
Debuggee, warum Haltepunkte gesetzt werden und wer dafür verantwortlich ist wird ebenfalls in
diesem Kapitel behandelt. Anhand von Symbol Tables erhält der Debugger Informationen wie
Strukturen und Variablen dargestellt werden. Hier werden die verschiedenen Symbolformate
vorgestellt und im Anschluss die Implementierung von den Funktionen Step Into, Step Over und Step
Out im Debugger erklärt.
Zum Schluss gibt es noch einen Ausblick auf das Arbeiten mit dem Visual Studio .NET Debugger.
Dieses exzellente Debuggingwerkzeug liefert viele Features die das Debuggen erleichtern und helfen,
Zeit zu sparen.
1 Einleitung
Anhand von Debugging werden die Ursachen für Bugs transparent gemacht. Im Zuge des Debuggings
können Prozesse gestoppt, Variablen gelesen und verändert werden. Es gibt dazu verschiedene
Werkzeuge die in dieser Seminararbeit erläutert und gegenübergestellt werden. Wichtig ist, zwischen
einem Debugger und einem Debugge zu unterscheiden. Unter einem Debugger versteht man einen
Prozess, der in der Lage ist, einen anderen Prozess in einer Debuggingbeziehung zu kontrollieren.
Debuggee bezeichnet dann einen Prozess, der unter einem Debugger gestartet wird. In manchen
Betriebssystemen wird statt Debugger auch „parent process“ und statt Debugge „child process
verwendet.
Debugging 2
4
2 Typen von Windows Debuggern
2.1 User-Mode Debugger
Wie der Name bereits verrät, werden User-Mode Debugger zum Debuggen von benutzerdefinierten
Applikationen eingesetzt. Das sind jene Applikationen die eine Benutzerschnittstelle (GUI)
verwenden. Dazu gehören solche Dienste, die von Windows angeboten werden. Das
Hauptkennzeichen von User-Mode Debuggern ist die Verwendung der Win32 Debugging API.
Bei Microsoft Windows 2000 und allen früheren Versionen von Microsoft Windows gab es bei
Prozessen, die unter der Win32 Debugging API liefen das Problem, dass auch der Debuggee beendet
wurde wenn der Debugger beendet wurde. Ab Microsoft Windows XP und Windows Server 2003 ist
dieses Problem nicht mehr vorhanden.
Interpretierte Programmiersprachen und welche die sich des „virtual machine“ (VM) Ansatzes
bedienen benutzen nicht die Win32 Debugging API da die komplette Debugging Umgebung von der
VM bereitgestellt wird.
2.2 Kernel-Mode Debuggers
Kernel-Mode Debugger sitzen zwischen der CPU und dem Betriebssystem. Wenn beispielsweise in
einem Kernel-Mode Debugger gestoppt wird, dann wird auch das Betriebssystem gestoppt. Dies spielt
besonders bei Synchronisation und Timing eine große Rolle.
2.2.1 Kernel Debugger (KD)
Der Kernel-Mode Debugger ist in NTOSKRNL.EXE, welche die wichtigste Kerneldatei darstellt,
enthalten. Anhand des Kernel-Mode Debuggers NTOSKRNL.EXE kann die CPU kontrolliert und
somit das Betriebssystem debuggt werden. Der KD ist im Debuggingwerkzeug von Microsoft
inkludiert und ist unter www.microsoft.com/ddk/debugging erhältlich. Weil der KD eine
Konsolenapplikation ist, kann er außerhalb von Microsoft nicht eingesetzt werden. Weiters ist es nicht
möglich den Kernel Debugger auf einem einzigen Computer auszuführen.
2.2.2 WinDBG
WinDBG ist wie der KD im Debuggingwerkzeug für Windows inkludiert. Beim WinDBG handelt es
sich um einen hybriden Debugger da er sowohl als Kernel-Mode als auch als User-Mode Debugger
Debugging 2
5
eingesetzt werden kann. Dabei können Programme gleichzeitig im User- und Kernel-Mode getestet
werden.
2.2.3 SoftICE
SoftICE ist der einzige kommerzielle Kernel-Mode Debugger auf dem Markt und kann auch als
einziger auf nur einem Computer ausgeführt werden. SoftICE sitzt, wie alle anderen Kernel-Mode
Debugger auch, zwischen der CPU und dem Betriebssystem. Beim Testen eines User-Mode
Programms wird das Betriebssystem zur Gänze gestoppt. Daher ist es leichter, zeitgesteuerte (timing)
Probleme leichter zu lösen. SoftICE ist der einzige Debugger der es erlaubt, multithreded
Applikationen zu debuggen.
Dadurch dass SoftICE zwischen der CPU und dem Betriebssystem sitzt, wird das Debuggen von
cross-porcess Interaktionen erleichtert. Es können in den Prozessen beliebig viele Haltepunkte
(breakpoints) gesetzt werden und zwischen diesen Haltepunkten, und daher auch zwischen den
Prozessen hin und her gesprungen werden. SoftICE erlaubt es auch zwischen dem User-Mode und
dem Kernel-Mode zu wechseln.
Als Hauptvorteil von SoftICE kann die weitaus größere Kollektion an Befehlen zur Ansicht von
Abläufen des Betriebssystems als bei KD und WinDBG gesehen werden. Mit diesen Befehlen können
etwa alle Zustände von synchronisierten Events, komplette HWND Informationen und exakte
Informationen zu den Threads im System transparent gemacht werden.
Der einzige Nachteil von SoftICE ist die schwierige Einarbeitung da dieser Debugger als eigenes
Betriebssystem angesehen werden kann.
2.3 Windows Betriebssystemunterstützung für Debuggees
2.3.1 Just-In-Time (JIT) Debugging
Just-In-Time Debugging macht es möglich, beim Absturz einer Applikation diese zu debuggen. Dabei
wird
im
Registry
Schlüssel,
HKEY-LOCAL-MACHINE\SOFTWARE\Microssoft\Windows
NT\CurrentVersion\AeDebug, der richtige Aufruf für den Debugger gesucht. Wenn es in diesem
Schlüssel
keine
Werte
gibt,
öffnet
Windows
Standardabsturzdialogbox.
Im AeDebug Schlüssel gibt es folgende Werte:
•
Auto
•
UserDebuggerHotKey
•
Debugger
XP
und
Windows
Server
2003
ihre
Debugging 2
6
Enthält Auto den Wert 0, so wird die oben erwähnte Standardabsturzdialogbox geöffnet und bei Wert
1 der Debugger automatisch gestartet. Im UserDebuggerHotKey kann der Dual- oder
Hexadezimalwert eines Zeichens gesetzt werden und dann bei der späteren Eingabe dieses Zeichens
zum Debugger gewechselt werden. Der Wert für Debugger ist der wichtigste der Drei. Er gibt den
Debugger an, der bei einem Absturz einer Applikation gestartet werden soll.
2.3.2 Automatisch in einem Debugger starten (Image File Execution Options)
Im Folgenden werde ich 2 Fälle erläutern die ein automatisches Starten in einem Debugger notwendig
machen. Windows Dienste und COM out-of-process Server fallen unter jene Applikationen die am
schwierigsten zu debuggen sind da diese Prozesse von anderen Prozessen gestartet werden können.
Bei Windows Diensten und COM out-of-process Servern ist ein hinzufügen des Prozesses zu einem
Debugger durch die DebugBreak API Funktion nicht möglich. Bei den Windows Diensten kann es
eine Zeitüberschreitung geben und Windows bricht den Dienst ab. Im anderen Fall, einen COM outof-process Server mit DebugBreak debuggen, wird eine Haltepunktausnahme abgefangen und der
COM out-of-process server gestoppt.
Unter Windows gibt es nun eine Möglichkeit eine Applikation in einem Debugger zu starten. Dazu
wird
im
Registry
Editor
im
Schlüssel
HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\Windows NT\CurrentVersion\Image File
Execution Options key ein neuer Schlüssel mit dem Namen der Applikation erzeugt. Beispielsweise
wird für die Applikation TEST.EXE ein TEST.EXE Schlüssel in der Registry angelegt. In diesem
Schlüssel muss nun ein neuer String mit dem Namen Debugger erzeugt werden. Diesem String wird
dann der Pfad plus der Name des gewünschten Debuggers zugewiesen. Beim Start der Applikation
TEST.EXE wird dann der Debugger automatisch gestartet. Diese Methode funktioniert jedoch nicht
bei der Verwendung von Visual Studio .NET als Debugger.
3 Ein einfacher Win32 Debugger
Ein minimaler Win32 Debugger verlangt kein Multithreading, User Interface oder sonst etwas. Das
folgende Pseudocodebeispiel illustriert mit welch geringen Mitteln ein Win32 Debugger erzeugt
werden kann.
void main ( void ) {
CreateProcess ( … DEBUG_ONLY_THIS_PROCESS …);
while ( 1 == WaitForDebugEvent ( ...) ) {
if ( EXIT_PROCESS ) {
break;
}
ContinueDebugEvent ( ... );
}
}
Debugging 2
7
Ein Win32 Debugger muss eine spezielle Flag übergeben, damit das Betriebssystem weiß, dass der
aufrufende Thread in eine Debuggingschleife geht um den gestarteten Prozess zu kontrollieren. Ein
Flag ist ein Hilfsmittel um bestimmte Zustände zu kennzeichnen. [Wikipedia 1]
Weiters muss der Debugger nachdem der Debuggee gestartet wurde in eine Schleife gehen und die
API
Funktion
WaitForDebugEvent
aufrufen,
wie
im
obigen
Codestück
illustriert,
um
Debuggingmitteilungen empfangen zu können. Es ist zu beachten, dass die Debugging API
Funktionen nur von dem Thread aufgerufen werden können, der CreateProcess aufgerufen hat.
4 Besonderheiten beim Debugging
4.1 Speicher lesen und schreiben
Das Lesen vom Speicher des Debuggees erfolgt mit Hilfe der Funktion ReadProcessMemory. Der
Debugger hat vollen Zugriff auf den Debugge wenn ihn der Debugger gestartet hat. Das von der
Funktion
CREATE_PROCESS_DEBUG_EVENT
PROCESS_VM_READ
und
PROCESS_VM_WRITE
retournierte
Zugriff.
Debugereignis
Verwendet
der
hat
Debugger
DebugActiveProcess, benötigt er auch SeDebugPrivileges.
Zur besseren Verständlichkeit möchte ich kurz das später verwendete Konzept Copy-Cn-Write
erklären. Bei dieser Methode wird der Speicherinhalt nicht wirklich kopiert um eine Speicherseite in
einem anderen Prozess verfügbar zu machen. Solange die Daten nur gelesen werden, reicht es aus,
dass beide Prozesse auf den gleichen physikalischen Speicherbereich zugreifen. Damit werden
überflüssige Kopien vermieden. Erst wenn einer der beiden Prozesse die Daten schreibt erzeugt der
Kernel eine Kopie im virtuellen Arbeitspeicher des schreibenden Prozesses. [Wikipedia 2]
Da die Speicherseiten meist zu ihrem Schutz nur Lesezugriffe zulassen, muss zuerst mit dem Aufruf
von VirtualQueryEx der Seitenschutz ermittelt werden. Mit diesem Seitenschutz und der API
Funktion VirtualProtectEx kann die Seite auf PAGE_EXECUTE_READWRITE gesetzt werden und
Windows ist dazu befähigt das zuvor angeführte Copy-On-Write durchzuführen. Nach dem Schreiben
in den Speicher muss der Originalseitenschutz wieder hergestellt werden.
4.2 Haltepunkte und Single Stepping
Ein Debugger benutzt Haltepunkte um den Debuggee kontrollieren zu können. Auch wenn vom
Anwender keine Haltepunkte gesetzt werden, setzt der Debugger welche um einen Funktionsaufruf
schrittweise (single stepping) kontrollieren zu können.
Debugging 2
8
Das Konzept zum Setzen eines Haltepunktes ist sehr einfach. Man braucht nur die Adresse, an der ein
Haltepunkt gesetzt werden soll. Dann wird der Wert des opcode an dieser Stelle gespeichert und die
Haltepunktanweisungen in die Adresse geschrieben. Der opcode, operation code, gibt die Nummer
eines Maschinenbefehls für einen Prozessortyp an. [Wikipedia 3]
Wird ein Haltepunkt beim Ausführen eines Programms erreicht, so muss das laufende Programm
unterbrochen werden und der Debugger aufgerufen werden. Um das unterbrochene Programm wieder
fortsetzen zu können, muss der Maschinenbefehl an der Stelle des Haltepunktes gerettet werden und
durch einen TRAP-Befehl ersetzt werden. Erreicht das Programm den TRAP-Befehl, so wird das
Programm unterbrochen. Dadurch wird der Debugger aufgerufen und seine Rücksprungadresse so
manipuliert, dass der Debugger nach dem Anzeigen des Programmzustandes zum geretteten Befehl
springt. Hinter diesem Befehl ist ein Sprung zum Befehl nach dem Haltepunkt. Mit diesem kann das
Programm wieder normal fortgesetzt werden. [Rechenberg und Pomberger 2002 S 731]
4.3 Symbol Tables, Symbol Engines and Stack Walking
Mit Symbol Tables, Debugging Symbole, werden hexadezimale Zahlen in Quelldateizeilen,
Funktionsnamen und Variablennamen umgewandelt. Symbol Tables enthalten Typinformation
anhand derer der Debugger die Originaldaten wie die im Programm verwendeten Strukturen und
Variablen darstellen kann.
4.3.1 Verschiedene Symbolformate
Das Common Object File Format (COFF) ist eines der ersten symbol table Formate und wurde mit
Windows NT eingeführt. Das COFF Format ist ein Teil einer umfangreichen Spezifikation mit der
UNIX Anbieter versuchten, einheitliche Formate für binäre Dateien zu erstellen. COFF wurde zuletzt
bei Visual C++ 6 eingesetzt.
Das C7 Format, auch CodeView genannt, tauchte das erste Mal als Teil von Microsoft C/C++ Version
7 auf. CodeView war auch der Name eines alten Microsoft Debuggers. Das C7 Format wurde soweit
aktualisiert, damit es Win32 Betriebssysteme unterstützt. Visual C++ 6 ist der letzte Compiler der
dieses Format unterstützt. Die Symbolinformation wurde nach dem Verweis an die Binärdatei hinten
angehängt.
Das zur Zeit meist verbreiteste Format ist PDB (Program Database) und wird von Visual C++, Visual
C# und Visual Basic .NET unterstützt. PDB speichert die Symbolinformation getrennt von der
Binärdatei. DBGs sind Dateien im PE-Format (Portable Executable, übertragbar ausführbar). Diese
Debugging 2
9
Dateien werden nicht vom Linker erstellt und enthalten andere Typen von Debuggingsymbolen wie
zum Beispiel COFF oder C7.
4.3.2 Symbolinformation abrufen
Mit DBGHELP.DLL von Microsoft war es zuerst nur möglich öffentliche Informationen wie
Funktionsnamen und elementare globale Variablen zu erhalten. Die neuen Versionen haben die
DBGHELP.DLL stark verbessert. Nähere Informationen dazu und die neueste Version gibt es im
Internet unter www.microsoft.com/ddk/debugging.
Mit ersten Versionen von Visual Studio .NET stellte Microsoft ein Interface für PDB Dateien zur
Verfügung. Dieses Debug Interface Access (DIA) SDK war jedoch nicht mehr als ein PDB Reader.
Es ließ also kein Stack Walking, wird später noch näher behandelt, zu. Erst durch das Visual Studio
.NET 2003 Release von DIA wurde Stack Walking möglich. Dieses DIA Interface ist pseudo Combasiert. Es wirkt schwerfällig und kann die Vorteile von COM nicht nützen.
Symbole werden in einer Art übersetzt, die dem Ablegen im Speicher ähnlich ist. Mit der Abbildung 1
möchte ich ein Beispiel zeigen, welchen Rotationen die Symbolexpansion unterliegt, wenn ein Pointer
zu einer Struktur expandiert wird. Der SymTagData Wert ist der Typ, der bezeichnet, dass die
folgende Rekursion ein Datentyp ist. In rekursiven Schritten wird solange runter gebrochen, bis man
einen Typ erreicht.
typedef struct tag_MYSTRUCT {
Int
iValue ;
Int * pdata ;
Char *szString
;
} MYSTRUCT , * LPMYSTRUCT;
Display a pointer to
a MYSTRUCT expansion;
MYSTRUCT * pMystruct
Debugging 2
10
Abbildung 1: Ein Beispiel für Symbolexpansion
4.3.3 Walking the Stack
Wie bereits vorher erwähnt ist das „spazieren im Kellerspeicher“ mit DBGHELP.DLL möglich. Dazu
gibt es die API Funktion StackWalk64 die auch von WDBG und WinDBG verwendet wird und die
Bedürfnisse zum stack walking bereitstellt. Bei optimiertem Code kann es jedoch zu Problemen
kommen.
4.4 Step Into, Step Over und Step Out
Step Into, Step Over und Step Out verlangen Source und Disassembly Sichten die es erlauben, die
gegenwärtige Ausführungszeile oder den gegenwärtigen Befehl im Auge zu behalten. Diese drei
Funktionen arbeiten mit one-shot Haltepunkte. Das bedeutet, dass die Haltepunkte nachdem sie
getriggert wurden wieder verworfen werden.
Bei Step Into muss unterschieden werden, ob das Debugging im source level oder disassembly level
erfolgt. Im source level sucht der Debugger mit der symbol engine die Adresse der Zeile, die als
nächstes ausgeführt wird. Wenn dann die nächste Zeile ein Aufrufbefehl (call instruction) ist, wird
vom Debugger an der ersten Adresse von der Funktion, die der Debuggee aufruft, ein one-shot
Haltepunkt gesetzt. Wenn die nächste Zeile keinen Aufrufbefehl darstellt, wird an dieser Stelle vom
Debugging 2
11
Debugger ein one-shot Haltepunkt erstellt. Danach lässt der Debugger den Debuggee über den zuvor
gesetzten Haltepunkt laufen. Wenn der Haltepunkt ausgelöst wird, ersetzt der Debugger an der Stelle
des one-shot Haltepunkts den opcode und gibt den Speicher der für den one-shot Haltepunkt benötigt
wurde frei.
Wird Step Into im disassembly level ausgeführt, wird die CPU vom Debugger zur Ausführung im
single step modus gezwungen.
Beim Step Over sucht der Debugger wie beim Step Into mit der symbol engine nach der nächsten
Zeile und macht an dieser Adresse ein partielles disassembly. Zum Unterschied zu Step Into setzt der
Debugger einen one-shot Haltepunkt nach dem Aufrufbefehl wenn die Zeile einen Aufruf darstellt.
Wenn der Step Out Befehl ausgewählt wird, durchläuft der Debugger den Stack und sucht die
Rückkehradresse für die aktuelle Funktion und setzt an dieser Adresse einen one-shot Haltepunkt.
5 Erweitertes debuggen mit Visual Studio .NET
In diesem Abschnitt werde ich den Microsoft Visual Studio .NET Debugger überblicksmässig
behandeln. Das Kapitel 5, „Multiple Breakpoints on a Single Line“ aus dem Buch Debugging
Applications for Microsoft .NET and Microsoft Windows von John Robbinson, gibt es im Internet
unter http://www.microsoft.com/mspress/books/sampchap/5822.asp. Das Entwicklungsteam des
Visual Studio .NET Debuggers hat über die letzten Jahre immer wieder große Verbesserung
geschafften. Das Ergebnis ist ein state-of-the-art Debuggingwerkzeug. Mit diesem Werkzeug ist das
Debuggen von Scripts, Microsoft Active Server Pages (ASP), Microsoft ASP.NET, .NET, XML Web
Services, native code und SQL möglich.
5.1 Erweitete Haltepunkte
In Visual Studio .NET ist es sehr einfach einen Haltepunkt in einer Zeile des Quellcodes zu setzen.
Dazu setzt man den Cursor in die Zeile in der ein Haltepunkt gesetzt werden soll, und drückt F9 (für
Defaulthaltepunkt). Nach John Robbins können mit diesen vor Ort Haltepunkte (location breakpoints)
99,46 % der Debuggingprobleme gelöst werden.
Mit dem Visual Studio .NET Debugger ist es auch möglich, Haltepunkte im Aufrufkellerspeicher (call
stack) zu setzen außer beim Debuggen von SQL. Dieses Feature hilft zur Durchführung von Stopps in
Rekursionen oder tief verschachtelten Kellerspeichern (stack).
Debugging 2
12
5.1.1 IntelliSense
IntelliSense bietet Hilfe beim Schreiben von Code und beim Setzen von Haltepunkten. Mit
IntelliSense ist es möglich Haltepunkte zu setzten, wenn nur der Namen der Klasse und der Methode
bekannt sind. Die Eingabe erfolgt in der Haltepunktdialogbox (breakpoint dialog box). Dabei ist die
Groß- und Kleinschreibung der Namen zu beachten, wenn es bei der Programmiersprache eine
Unterscheidung zwischen Groß- und Kleinschreibung gibt (case sensitiv). In native C++ ist das setzen
von Haltepunkten manchmal nicht möglich da die Methodennamen verdeckt sein können.
Angenommen wir haben ein größeres Projekt mit mehreren Klassen und Methoden. Es gibt eine
Methode mit dem Namen Test die in vielen Klassen verwendet wird. Wird nun der Name dieser
Methode in der Haltepunktdialogbox eingegeben, zeigt IntelliSense alle Klassen an die diese Methode
verwenden. Es können dann alle oder nur einzelne der Angezeigten Haltepunkte ausgewählt werden.
Wird in der Haltepunktdialogbox nur der Name der Klasse eingegeben, so werden alle Methoden
dieser Klasse angezeigt. Das funktioniert jedoch nur in C++ und hilft beim Auffinden von totem
Code.
Weiters können Haltepunkte mit der Find Combo Box gesetzt werden. Dazu muss nur der Name der
Methode bei der ein Haltepunkt gesetzt werden soll in die Find Combo Box eingegeben und F9
gedrückt werden. IntelliSense setzt für diese Methode, wenn sie vorhanden ist, einen Haltepunkt. Ist
diese Methode überladen, so wird für jede überladene Methode ein Haltepunkt gesetzt.
5.1.2 Modifizieren von vor Ort Haltepunkten (location breakpoints)
Vor Ort Haltepunkt können anhand von Trefferzähler (hit counts) und bedingten Ausdrücken
(conditional expressions) effizienter gemacht werden.
5.1.2.1 Trefferzähler
Der Trefferzähler gibt dem Debugger bescheid, wie oft eine bestimmte Codezeile zuvor ausgeführt
werden muss bevor dieser stoppen darf. Diese Modifizierung macht das Halten in Schleifen sehr
einfach. Wenn der Debugger gestoppt wird, gibt der Trefferzähler Auskunft wie oft der Haltepunkt
ausgeführt wurde. Der Trefferzähler kann jederzeit in der Haltepunktdialogbox auf die Zahl Null
gestellt werden.
5.1.2.2 Bedingte Ausdrücke
Mit dieser Erweiterung bei einem Haltepunkt kann bei richtiger Anwendung sehr viel Zeit gespart
werden. Ein vor Ort Haltepunkt mit einem bedingtem Ausdruck wird nur getriggert, wenn die
Debugging 2
13
Auswertung des bedingten Ausdrucks wahr liefert oder sich von der letzten Auswertung
unterscheidet.
5.1.3 Mehrere Haltepunkte in einer Zeile
Von der Möglichkeit mehrere Haltepunkte in einer Zeile zu setzten wird man nicht jeden Tag
gebrauch machen da es keine leichte Sache ist. In früheren Versionen von Visual Studio .NET war
das Setzen von mehreren Haltepunkten in einer Zeile nicht möglich. Der erste Haltepunkt wird durch
klicken der rechten Maustaste im Seitenrand und Angabe eines bedingten Ausdrucks gesetzt. Der
zweite Haltepunkt kann dann mit der Haltepunktdialogbox gesetzt werden wobei auch wieder ein
bedingter Ausdruck angegeben wird. Im Haltepunktfenster (breakpoint window) wird der Haltepunkt
fett angezeigt, der für den Halt verantwortlich ist.
5.2 Das Beobachtungsfenster (watch window)
Mit dem Beobachtungsfenster (watch window) können Fehler sehr schnell behoben werden. Es
können Variablen nicht nur gelesen bzw. beobachtet sondern auch sehr einfach verändert werden. Das
Beobachtungsfenster besitzt einen kompletten Ausdrucksevaluator. Um beispielsweise etwas als
Integer zu sehen, was kein Integer ist, kann man wie in einer aktiven Programmiersprache einen Cast
durchführen.
6 Zusammenfassung
Diese Arbeit zeigt wie zwischen den einzelnen Debuggern unterschieden werden kann. Aus der durch
die Arbeit gewonnene Transparenz der verschiedenen Debuggern und deren Arbeitsweisen möchte
ich noch anmerken, dass es sich bei diesen Debuggern um sehr mächtige und hilfreiche, in Bezug auf
Zeit- und dadurch auch Kostenersparnis, Werkzeuge handelt. Um die Mächtigkeit zu unterstreichen
erinnere ich an die Haltepunkte und deren Erweiterungen wie Trefferzähler und bedingten
Ausdrücken.
Debugging 2
14
7 Literaturverzeichnis
[Rechenberg und Pomberger 2002 S 731]
P. Rechenberg, G. Pomberger, Informatik-Handbuch,
Carl Hanser Verlag, 2002, S 731.
[Robbins 2002]
John Robbins, Debugging Applications for Microsoft
.NET and Microsoft Windows w. CD-ROM, Microsoft
Press International, May 2002, S 157-234.
[Wikipedia 1]
Wikipedia,
die
freie
Enzyklopädie,
Flag,
http://de.wikipedia.org/wiki/Flag, Mai 2005.
[Wikipedia 2]
Wikipedia, die freie Enzyklopädie, Copy-On-Write,
http://de.wikipedia.org/wiki/Copy-On-Write, Mai 2005.
[Wikipedia 3]
Wikipedia,
die
freie
Enzyklopädie,
Opcode,
http://de.wikipedia.org/wiki/Opcode, Mai 2005.
8 Abbildungsverzeichnis
Abbildung 1: Ein Beispiel für Symbolexpansion.......................................................10
Document
Kategorie
Technik
Seitenansichten
2
Dateigröße
192 KB
Tags
1/--Seiten
melden