Debugger - Debugger

Ein Debugger oder Debugging-Tool ist ein Computerprogramm, das verwendet wird, um andere Programme (das "Ziel"-Programm) zu testen und zu debuggen . Der Hauptzweck eines Debuggers besteht darin, das Zielprogramm unter kontrollierten Bedingungen auszuführen, die es dem Programmierer ermöglichen, seine laufenden Operationen zu verfolgen und Änderungen der Computerressourcen (meist Speicherbereiche, die vom Zielprogramm oder dem Betriebssystem des Computers verwendet werden) zu überwachen, die auf fehlerhafter Code. Zu den typischen Debugging-Funktionen gehören die Möglichkeit, das Zielprogramm an bestimmten Punkten auszuführen oder anzuhalten, den Inhalt von Speicher, CPU-Registern oder Speichergeräten (wie Plattenlaufwerken) anzuzeigen und Speicher- oder Registerinhalte zu ändern, um ausgewählte Testdaten einzugeben, die möglicherweise Ursache für eine fehlerhafte Programmausführung sein.

Der zu untersuchende Code könnte alternativ auf einem Befehlssatzsimulator (ISS) ausgeführt werden, einer Technik, die eine große Leistung beim Anhalten ermöglicht, wenn bestimmte Bedingungen auftreten, die jedoch normalerweise etwas langsamer ist als die direkte Ausführung des Codes auf dem entsprechenden (oder der gleiche) Prozessor. Einige Debugger bieten zwei Betriebsmodi, vollständige oder teilweise Simulation, um diese Auswirkungen zu begrenzen.

Eine " Trap " tritt auf, wenn das Programm aufgrund eines Programmierfehlers oder ungültiger Daten nicht normal fortgesetzt werden kann. Beispielsweise könnte das Programm versucht haben, einen Befehl zu verwenden, der in der aktuellen Version der CPU nicht verfügbar ist, oder versucht, auf nicht verfügbaren oder geschützten Speicher zuzugreifen . Wenn das Programm "abfängt" oder eine voreingestellte Bedingung erreicht, zeigt der Debugger normalerweise die Position im Originalcode an, wenn es sich um einen Debugger auf Quellebene oder einen symbolischen Debugger handelt , der heute häufig in integrierten Entwicklungsumgebungen verwendet wird . Wenn es sich um einen Low-Level-Debugger oder einen maschinensprachlichen Debugger handelt , zeigt er die Zeile in der Disassemblierung an (es sei denn, er hat auch Online-Zugriff auf den Originalquellcode und kann den entsprechenden Codeabschnitt aus der Assembly oder Kompilierung anzeigen).

Merkmale

In der Regel bieten Debugger einen Abfrageprozessor, einen Symbolresolver, einen Ausdrucksinterpreter und eine Debug-Unterstützungsschnittstelle auf der obersten Ebene. Debugger bieten auch ausgefeiltere Funktionen wie das schrittweise Ausführen eines Programms ( Einzelschritt oder Programmanimation ), das Anhalten ( Brechen ) (das Programm anhalten , um den aktuellen Zustand zu untersuchen) bei einem bestimmten Ereignis oder einer bestimmten Anweisung mittels eines Haltepunkts und Verfolgen der Werte von Variablen. Einige Debugger haben die Möglichkeit, den Programmstatus während der Ausführung zu ändern. Es kann auch möglich sein, die Ausführung an einer anderen Stelle im Programm fortzusetzen, um einen Absturz oder einen logischen Fehler zu umgehen.

Die gleiche Funktionalität, die einen Debugger zum Korrigieren von Fehlern nützlich macht, ermöglicht es, ihn als Software-Cracking- Tool zu verwenden, um Kopierschutz , digitale Rechteverwaltung und andere Softwareschutzfunktionen zu umgehen . Es macht es oft auch als allgemeines Verifikationswerkzeug, Fehlerabdeckung und Leistungsanalysator nützlich , insbesondere wenn Befehlspfadlängen angezeigt werden. Frühe Mikrocomputer mit festplattenbasiertem Speicher profitierten oft von der Fähigkeit, beschädigte Verzeichnis- oder Registrierungsdatensätze zu diagnostizieren und wiederherzustellen, als gelöscht markierte Dateien "wiederherzustellen" oder den Passwortschutz für Dateien zu knacken.

Die meisten Mainstream-Debugging-Engines wie gdb und dbx bieten konsolenbasierte Befehlszeilenschnittstellen . Debugger-Front-Ends sind beliebte Erweiterungen von Debugger-Engines, die IDE- Integration, Programmanimation und Visualisierungsfunktionen bieten .

Debugging aufzeichnen und wiedergeben

Record and Replay Debugging , auch bekannt als "Software Flight Recording" oder "Program Execution Recording", erfasst Änderungen des Anwendungszustands und speichert sie bei jeder Ausführung jedes Befehls in einem Programm auf der Festplatte. Die Aufzeichnung kann dann immer wieder abgespielt und interaktiv debuggt werden, um Fehler zu diagnostizieren und zu beheben. Das Debuggen von Aufzeichnungen und Wiedergaben ist sehr nützlich für das Remote-Debugging und zum Beheben von intermittierenden, nicht deterministischen und anderen schwer reproduzierbaren Fehlern.

Reverse-Debugging

Einige Debugger enthalten eine Funktion namens " Reverse Debugging ", auch bekannt als "Historisches Debuggen" oder "Rückwärts-Debugging". Diese Debugger ermöglichen es, die Ausführung eines Programms zeitlich rückwärts zu schalten. Verschiedene Debugger enthalten diese Funktion. Microsoft Visual Studio (2010 Ultimate Edition, 2012 Ultimate, 2013 Ultimate und 2015 Enterprise Edition) bietet IntelliTrace-Reverse-Debugging für C#, Visual Basic .NET und einige andere Sprachen, jedoch nicht für C++. Reverse Debugger gibt es auch für C, C++, Java, Python, Perl und andere Sprachen. Einige sind Open Source; einige sind proprietäre kommerzielle Software. Einige Reverse-Debugger verlangsamen das Ziel um Größenordnungen, aber die besten Reverse-Debugger verursachen eine Verlangsamung von 2× oder weniger. Reverse Debugging ist für bestimmte Arten von Problemen sehr nützlich, wird aber noch nicht häufig verwendet.

Sprachabhängigkeit

Einige Debugger arbeiten mit einer einzigen spezifischen Sprache, während andere mehrere Sprachen transparent verarbeiten können. Wenn beispielsweise das Hauptzielprogramm in COBOL geschrieben ist, aber Subroutinen in Assemblersprache und PL/1- Subroutinen aufruft , muss der Debugger möglicherweise dynamisch die Modi wechseln, um die auftretenden Sprachänderungen zu berücksichtigen.

Speicherschutz

Einige Debugger enthalten auch Speicherschutz, um Speicherverletzungen wie Pufferüberlauf zu vermeiden . Dies kann in Transaktionsverarbeitungsumgebungen äußerst wichtig sein, in denen Speicher dynamisch von Speicherpools auf Task-für-Task-Basis zugewiesen wird.

Hardware-Unterstützung für das Debugging

Die meisten modernen Mikroprozessoren haben mindestens eine dieser Funktionen in ihrem CPU-Design , um das Debuggen zu erleichtern:

  • Hardwareunterstützung für die Einzelschrittausführung eines Programms, z. B. das Trap-Flag .
  • Ein Befehlssatz, der die Virtualisierungsanforderungen von Popek und Goldberg erfüllt , erleichtert das Schreiben von Debugger-Software, die auf derselben CPU wie die zu debuggende Software ausgeführt wird; eine solche CPU kann die inneren Schleifen des zu testenden Programms mit voller Geschwindigkeit ausführen und dennoch unter Debugger-Steuerung bleiben.
  • Die systeminterne Programmierung ermöglicht es einem externen Hardware-Debugger, ein zu testendes System neu zu programmieren (beispielsweise durch Hinzufügen oder Entfernen von Befehlshaltepunkten). Viele Systeme mit einer solchen ISP-Unterstützung haben auch andere Hardware-Debugging-Unterstützung.
  • Hardware-Unterstützung für Code- und Daten- Breakpoints , wie Adress- und Datenwert-Komparatoren oder mit deutlich höherem Aufwand Page-Fault- Hardware.
  • JTAG- Zugriff auf Hardware-Debugging-Schnittstellen wie auf Prozessoren mit ARM-Architektur oder über den Nexus- Befehlssatz. Prozessoren, die in eingebetteten Systemen verwendet werden, verfügen normalerweise über eine umfassende JTAG-Debug-Unterstützung.
  • Mikrocontroller mit nur sechs Pins müssen JTAG-Substitute mit geringer Pinanzahl wie BDM , Spy-Bi-Wire oder debugWIRE auf dem Atmel AVR verwenden . DebugWIRE verwendet beispielsweise eine bidirektionale Signalisierung am RESET-Pin.

Debugger-Frontends

Einige der leistungsfähigsten und beliebtesten Debugger implementieren nur eine einfache Befehlszeilenschnittstelle (CLI) – oft um die Portabilität zu maximieren und den Ressourcenverbrauch zu minimieren. Entwickler halten das Debuggen über eine grafische Benutzeroberfläche (GUI) in der Regel für einfacher und produktiver. Dies ist der Grund für visuelle Frontends, die es Benutzern ermöglichen, untergeordnete CLI-only Debugger über eine grafische Benutzeroberfläche zu überwachen und zu steuern . Einige GUI-Debugger-Front-Ends sind so konzipiert, dass sie mit einer Vielzahl von reinen CLI-Debuggern kompatibel sind, während andere auf einen bestimmten Debugger ausgerichtet sind.

Liste der Debugger

Einige weit verbreitete Debugger sind:

Frühere Minicomputer- Debugger umfassen:

Frühere Mainframe- Debugger umfassen (im Datum der Veröffentlichungsreihenfolge):

  • 1974 OLIVER CICS TEST/DEBUG
  • 1980 SIMON BATCH TEST/DEBUG
  • 1985 CA/EZTEST
  • 1990 XPEDITER und Expediter CICS

Aktuelle Mainframe-Debugger:

Siehe auch

Verweise

  • Sanjeev Kumar Aggarwal; M. Sarath Kumar (2003). "Debugger für Programmiersprachen". In YN Srikant; Priti Shankar (Hrsg.). Das Compiler-Design-Handbuch: Optimierungen und Maschinencode-Generierung . Boca Raton, Florida: CRC-Presse . S. 295–327. ISBN 978-0-8493-1240-3.
  • Jonathan B. Rosenberg (1996). Funktionsweise von Debuggern: Algorithmen, Datenstrukturen und Architektur . John Wiley & Söhne . ISBN 0-471-14966-7.

Zitate

Externe Links