Debugger

Diese Übersetzung ist unvollständig. Bitte helfen Sie, diesen Artikel aus dem Englischen zu übersetzen.

Der JavaScript Debugger ermöglicht es dir, schrittweise durch den JavaScript Code zu gehen und dabei seinen Zustand zu sehen und zu verändern, um Fehler im Code einfacher zu finden.

Man kann ihn benutzen, um Code lokal in Firefox zu debuggen, oder remote - zum Beispiel auf einem Firefox-OS-Gerät oder einem Firefox auf Android. In dieser Anleitung wird davon ausgegangen, dass du lokalen Code bearbeitest, aber das meiste trifft auch für das Remote-Debugging zu. Zu den Unterschieden siehe die Anleitung zum Remote-Debugging.

Um den Debugger zu öffnen, wählt man einfach "Debugger" aus dem Webentwickler-Untermenü von Firefox (oder im Werkzeuge-Menü, wenn die Menüleiste benutzt wird oder du auf Mac OS X arbeitest), oder indem man die Tastenkombination (das "Shortcut") Control-Shift-S (Command-Option-S auf Mac) auf der Tastatur drückt.

Die Toolbox erscheint am unteren Rand des Browserfensters. Als Standardeinstellung ist der Debugger aktiviert. So sieht sie aus, wenn sie zum ersten mal geöffnet wird:

Und das ist die Ansicht während des Debugging-Prozesses:

In dieser Anleitung werden wir uns zunächst kurz die Benutzeroberfläche des Debuggers ansehen und dann beschreiben, wie man einige häufig vorkommende Debuggingaufgaben durchführt.

Die Benutzeroberfläche des Debuggers

Die Benutzeroberfläche ("User Interface", UI) ist in vier Bereiche aufgeteilt, die wir uns nacheinander ansehen werden:

  • die Werkzeugleiste ("toolbar")
  • die Quellcode-Dateiliste ("source list pane")
  • der Quellcodebereich ("source pane")
  • die Variablenliste ("variables pane")

Die Quellcode-Dateiliste

Auf der linken Seite siehst du eine Liste mit allen JS-Quelldateien, die von der aktuellen Seite geladen wurden. Man kann jede davon auswählen, um sie zu debuggen.

Die Quelldateien sind unter Überschriften eingeordnet, die angeben, von wo sie geladen wurden. Hier ein Beispiel für eine Quellcode-Dateiliste, wenn eine Seite von developer.mozilla.org geladen ist:

Die Dateinamen und Domains stimmen überein mit den folgenden script-Tags im Quellcode der Seite:

<script src="/en-US/jsi18n/build:8987063"></script>
<script src="https://login.persona.org/include.js" type="text/javascript"></script>
<script src="//mozorg.cdn.mozilla.net/en-US/libs/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="//mozorg.cdn.mozilla.net/en-US/tabzilla/tabzilla.js" async></script>

In der Quellcode-Dateiliste kann man einfach eine der Dateien anklicken, um sie im Quellcodebereich anzeigen und untersuchen zu können.

Haltepunkte ("Breakpoints"), die man durch Klick neben eine Codezeile gesetzt hat, erscheinen unter dem Dateinamen.Mit der Checkbox kann man Breakpoints an- und ausschalten. Durch Rechts-Klick auf einen Brakepoint-Eintrag in der Liste kann man ein Kontextmenü anzeigen lassen, mit dem man

  • einzelne oder alle Haltepunkte aktivieren oder deaktivieren kann (oder alle Haltepunkte bis auf den angeklickten)
  • Bedingungen ("conditions") definieren kann, unter denen die Ausführung an dieser Stelle unterbrochen werden soll (oder diese Bedingungen verändern, wenn sie bereits gesetzt sind)

Durch Klick auf den "Augapfel" kann man das Verdecken ("black boxing") für eine bestimmte Quelle an- und abschalten (z.B. Sprünge in JavaScript-Bibliotheken verhindern). Mehr Informationen dazu findest du unter "Black box a source".

Quellcodebereich

Hier wird die aktuell geladene JavaScript-Datei angezeigt. Haltepunkte ("Breakpoints", im Bild "Breakpoint Set") sind die blauen Kreise neben den Zeilennummern, während Haltepunkte, an der die Code-Ausführung aktuell gestoppt wurde, einen grünen Pfeil innerhalb des Kreises haben ("Breakpoint Hit"):

Im Quellcodebereich kann man über das Kontextmenü folgende Aufgaben erledigen:

  • Breakpoints setzen
  • bedingte Breakpoints setzen
  • einen Überwachungsausdruck für die Auswahl hinzufügen
  • die Skriptsuche benutzen bzw. mit Hilfe eines solchen Filters suchen

Werkzeugleiste

Die Werkzeugleiste ("toolbar") besteht aus vier Teilen:

  • eine Buttonleiste, mit der man die Bewegung durch das Script steuern kann (Pause/Weiter, Hineinspringen, Verlassen, Ausführen)
  • eine Visualisierung des "Call stack" (Aufrufliste)
  • der Scriptfilter
  • Buttons, mit denen man die Variablenliste und die Debugger-Einstellungen ein- und ausklappen kann

Die vier Buttons auf der linken Seite haben folgende Funktionen:

  • Pause/Weiter (F6): Unterbricht die Skript-Ausführung bzw. setzt sie fort. Wenn der Schalter blau und "gedrückt" dargestellt wird wie oben, ist die Ausführung unterbrochen - entweder weil du selbst diesen Button gedrückt hast, oder weil sie an einem Breakpoint (Haltepunkt) angekommen ist. ("Pause/Resume")
  • Ausführen (F7): Führt die aktuelle JavaScript-Codezeile aus und springt zur nächsten. ("Step over")
  • Hineinspringen (F8): Springt in die Funktion, die in der aktuellen JavaScript-Zeile aufgerufen wird. ("Step into")
  • Verlassen (Shift-F8): Lässt das Skript durchlaufen (und führt es aus), bis die aktuelle Funktion beendet ist. ("Step out")

Die visuelle Darstellung des "Call stack" (Liste der Code-Unterbrechungen, an denen  eine Ebene tiefer in eine neue Funktion gesprungen wurde) zeigt die Liste aller Code-Stellen an denen Funktionsaufrufe zum aktuellen Breakpoint geführt haben. Über diese Liste kann man herausfinden, wie das Programm "an die aktuelle Stelle gekommen ist".

Durch Klick auf die Einträge wird im Quellcodebereich die Absprungstelle angezeigt und man kann nachvollziehen, von wo gesprungen wurde. Gleichzeitig werden in der Variablenliste die Variablenwerte zum Zeitpunkt des jeweiligen Funktionsaufrufs anzeigt. Oft lässt sich dadurch herausfinden, ob und warum Parameter falsch übergeben wurden und wo der eigentliche Fehler aufgetreten ist. Auch wenn Funktionen von verschiedenen Stellen im Code aufgerufen werden, lässt sich über den Stack herausfinden, um welchen Fall es sich handelt.

Skriptsuche

Mit der Skriptsuche ("script filter") kann man alle drei Debugger-Bereiche durchsuchen. Man kann dem Suchbegriff eines der folgenden Sonderzeichen voranstellen, um verschiedene Sonderfunktionen zu nutzen.

Prefix Function
Nichts Skripte durchsuchen, die in der Quellcodeliste angezeigt werden.
! In sämtlichen Dateien nach dem Suchbegriff suchen.
@ Nur nach Funktions-Definitionen in allen Dateien suchen, die den Begriff enthalten.
# Nur in der Datei, die aktuell im Quellcodebereich angezeigt wird, nach dem Begriff suchen.
: Zu einer Zeilennummer springen (in der aktuell im Quellcodebereich angezeigten Datei).
* Variablen durchsuchen, die in der Variablenliste angezeigt werden.

Diese Optionen werden in einem Popup angezeigt, wenn du in das Suchfeld klickst, und sie sind außerdem über das Kontextmenü im Quellcodebereich erreichbar. Die Sonderzeichen können auch kombiniert werden, um präzisere Suchen machen: "file.js:12" öffnet zum Beispiel file.js und springt in Zeile 12. "mod#onLoad" sucht in allen Dateien, die "mod" im Namen enthalten nach dem Begriff "onLoad". Mit der Return-/Enter-Taste kann von einem zum nächsten Ergebnis gesprungen werden.

Debugger-Einstellungen

Am rechten Ende der Werkzeugleiste befinden sich zwei weitere Buttons. Der erste schaltet zwischen Ein- und Ausblenden der Variablenliste hin und her. Mit dem zweiten kann man zwischen verschiedenen Debugger-Einstellungen umschalten:

With this option enabled, the debugger will automatically detect minified JS files and pretty-print them.

Auto Prettify Minified Sources

Ist diese Option eingeschaltet, findet der Debugger automatisch minimierte JavaScript-Dateien und stellt sie in lesbarer Form dar.

Pause bei Exceptions

Skriptausführung automatisch unterbrechen, wenn eine JavaScript-Exception geworfen wird.
Ignore caught exceptions

Wenn diese Einstellung gesetzt ist (Voreinstellung) und "Pause bei Exceptions" aktiviert ist, wird nur noch bei Fehlern unterbrochen, die nicht mit try-catch abgefangen werden. Diese Einstellung ist Standard, weil man davon ausgehen kann, dass abgefangene Exceptions im Programm ordnungsgemäß behandelt werden.

Neue Option in Firefox 26.

Show panes on startup Wenn diese Option aktiviert ist, wird die Variablenliste des Debuggers angezeigt, sobald der Debugger zum ersten mal aktiviert wird.
Show only enumerable properties Enabling this option adds a "Filter variables" search box to the variables panel, so that you can filter the displayed list of variables.
Show variables filter box Do not display non-enumerable JavaScript properties
Show original sources Enabling this option will make the debugger use source maps, if they are available, to display the original source for code which has been combined, minified, or even compiled to JavaScript from a language like CoffeeScript.

Variablenliste

In der Variablenliste kann man sehen, welche Werte die Variablen an einer bestimmten Stelle im Programm gerade haben - und man kann sie sogar für Versuche manuell verändern und das Skript dann weiterlaufen lassen:

Variablenwerte beobachten

Die Variablen sind nach Geltungsbereich ("scope") gruppiert: im Funktions-Scope sieht man die (standardmäßig vorhandenen) Werte von arguments und this und lokale Variablen, die in der Funktion definiert wurden (im Beispiel: user und greeting).

Ähnlich verhält es sich mit globalen Variablen, die auf der obersten Ebene des JavaScript-Files (also nicht in Funktionen) definiert wurden - im Bild etwa greetme, aber auch standardmäßig vorhandene Variablen wie localStorage und console.

Objekte können mit dem kleinen Pfeil links von ihnen auf- und zugeklappt werden. Dadurch werden ihre Eigenschaften (und Funktionen) und deren Werte sichtbar.

Wenn man mit dem Cursor über die Variablen fährt, wird ein Tooltip mit weiteren Informationen angezeigt - bei Rollover über das greeting-Objekt wird zum Beispiel "configurable enumerable writable" angezeigt. Weitere Details zur Bedeutung dieser Eigenschaften unter Object.defineProperty().

Die angezeigten Variablen lassen sich filtern - entweder durch Nutzung des "*"-Modifiers in the Skriptsuche, oder durch Text-Eingabe des Filters (#,!,...) vor dem Suchbegriff im Suchfeld, wenn diese Option in den Debugger-Einstellungen aktiviert wurde.

Variablenwerte verändern

Variablenwerte können einfach manuell verändert werden, indem man auf die Werte klickt und einen anderen Wert eingibt. Wenn man etwa auf "Hi, Dr. Nick!" klickt, den Variablenwert von greeting, kann man die Begrüßung ändern und das Programm mit diesem Wert weiter arbeiten lassen.

Überwachungsausdrücke

Überwachungsausdrücke sind Ausdrücke, die jedesmal ausgewertet werden, wenn die Code-Ausführung gestoppt wird. Mit Hilfe von Überwachungsausdrücken kann man sich einen Überblick über Werte verschaffen, die nicht direkt in der Variablenliste angezeigt werden - wie etwa bestimmte Eigenschaften eines Objekts, die für das Verständnis des Codeablaufs gerade erforderlich sind (siehe Beispiel user.value im Bild). Oder Variablen im Code, die nicht mit var deklariert wurden und daher vom Debugger nicht in der Liste angezeigt werden - oder Werte, die nur mit einer getter-Methode ausgelesen werden können (wie etwa user.getValue("something")) oder jQuery-Ausdrücke wie $("div.myclass>table").

Einfach auf "Überwachungsausdruck hinzufügen" über der Variablenliste klicken ("Add watch expression") und einen Ausdruck genauso eingeben, wie man es im Code an der aktuellen Stelle machen würde, um einen Wert zu erhalten. Dieser Wert wird dann, während man durch den Code geht, bei jedem Programm-Stop berechnet und wie die Werte der Variablen in der Liste angezeigt.Auf diese Weise kann man beim Durchlaufen des Programmes dabei zusehen, wie bestimmte Werte sich ändern. In dem Moment, wo eine Veränderung stattfindet, wird der Überwachungsausdruck kurz gelb hinterlegt, so dass man die Änderungen auch aus dem Augenwinkel mitbekommt, während man den Programmcode liest.

Selbstverständlich kann man auch mehrere Ausdrücke gleichzeitig in der Liste überwachen. Um einen Ausdruck wieder zu entfernen, klickt man einfach auf das kleine "x", das rechts neben dem Überwachungsausdruck erscheint, wenn man mit dem Cursor darüber fährt.

Wie kann ich...?

den Debugger öffnen

Einfach im Webentwickler-Submenü "Debugger" auswählen (oder in der Firefox-Menüleiste unter "Werkzeuge > Webentwickler > Debugger" klicken, falls du Mac OS X nutzt oder die Menüleiste eingeblendet hast). Alternativ auch mit Control-Shift-S (bzw. Command-Option-S auf Mac).

eine Quelldatei finden

Quelldateien ("source files") sind leicht zu finden: Wenn der Debugger geöffnet ist, werden alle JavaScript Quelldateien ("source files") links in der Quellcodeliste aufgelistet. Wenn die Liste zu lang ist, ist es of einfacher, die Skriptsuche oben rechts zu benutzen.

Codestellen in einer Datei finden

Um eine Funktion zu finden, nach einem Stichwort zu suchen oder in eine bestimmte Zeile im Code zu sprichen, der im Quellcodebereich geöffnet ist, kann man die Spezialfilter der Skriptsuche verwenden.

Breakpoint setzen

Um einen Haltepunkt ("breakpoint") in einer Datei zu setzen, die im Quellcodebereich geöffnet ist:

  • etweder auf die Zeilennummer neben der Codezeile klicken, wo unterbrochen werden soll
  • oder über der Codezeile selbst das Kontextmenü öffnen (Rechtsklick, Ctrl-Klick) und dort "Haltepunkt hinzufügen" wählen ("Add Breakpoint").

Jeder Breakpoint wird an drei Stellen im Debugger angezeigt:

  • in der Quellcodeliste unter dem Dateinamen
  • die Zeile im Quellcodebereich ist neben den Zeilennummern mit einem blauen Kringel markiert
  • die graue Leiste rechts neben der Quellcode-Scrollbar zeigt alle Haltepunkte als kleine blaue Kästchen (im Maßstab der Scrollbar, also auch aktuell im Quellcodebereich nicht sichtbare Haltepunkte)

In dem Screenshot unten siehst du Breakpoints in den Zeilen 7 und 65 der JavaScript-Datei:

Einen bedingten Breakpoint setzen

Um einen bedingten Haltepunkt  ("conditional breakpoint") zu setzen, an dem nur in bestimmten Fällen unterbrochen werden soll, öffnet man in der betreffenden Zeile das Kontextmenü und wählt "Bedingten Haltepunkt hinzufügen" ("Add conditional breakpoint"). In dem Textfeld, das sich daraufhin öffnet, kann einfach ein Boolscher Ausdruck eingesetzt werden. Die Syntax ist genau die gleiche wie in der Klammer einer if-Anweisung:

Um die Haltebedingung ("condition") zu verändern oder einem "normalen" Breakpoint nachträglich eine Bedingung hinzuzufügen, kann einfach das Kontextmenü auf dem Breakpoint geöffnet werden und "Haltebedingung  hinzufügen" ("Configure conditional breakpoint") gewählt werden:

Breakpoint deaktivieren

Um einen Brakepoint außer Kraft zu setzen ("disable a breakpoint") ohne ihn zu löschen:

  • entweder: Häkchen in der Checkbox neben dem Breakpoint-Eintrag in der Quellcodeliste entfernen
  • oder: über das Kontextmenü über dem Eintrag in der Quellcodeliste und dort "Haltepunkt deaktivieren" ("Disable breakpoint") klicken

Dem Programmablauf folgen

Wenn die Ausführung des Codes an einem Breakpoint gestoppt wird, kannst du Schritt für Schritt die Abarbeitung Programmzeilen und einzelner Befehle folgen. Dazu verwendet man die vier Buttons (Pause/Weiter, Hineinspringen, Verlassen, Ausführen) oben links in der Werkzeugleiste ("toolbar"):

Die vier Buttons auf der linken Seite haben folgende Funktionen:

  • Pause/Weiter (F6): Unterbricht die Skript-Ausführung bzw. setzt sie fort. Wenn der Schalter blau und "gedrückt" dargestellt wird wie oben, ist die Ausführung unterbrochen - entweder weil du selbst diesen Button gedrückt hast, oder weil sie an einem Breakpoint (Haltepunkt) angekommen ist. ("Pause/Resume")
  • Ausführen (F7): Führt die aktuelle JavaScript-Codezeile aus und springt zur nächsten. ("Step over")
  • Hineinspringen (F8): Springt in die Funktion, die in der aktuellen JavaScript-Zeile aufgerufen wird. ("Step into")
  • Verlassen (Shift-F8): Lässt das Skript durchlaufen (und führt es aus), bis die aktuelle Funktion beendet ist. ("Step out")

Source Maps

JavaScript-Quellcode wird oft aus mehreren Dateien zusammengefasst und das Ergebnis wird "minified" (komprimiert), um Serverbelastung und Ladezeiten zu optimieren. Immer häufiger ist das geladene JavaScript auch Maschinen-generiert, zum Beispiel aus Sprachen wie CoffeeScript.

Durch die Nutzung von source maps, kann der Debugger den gerade ausgeführten Code auf JS-Dateien "mappen", die für Menschen bequemer lesbar sind - also die entsprechenden Stellen in den Menschen-lesbaren Dateien anzeigen, was das Debuggen sehr erleichtert.

Dazu muss man dem Debugger mitteilen, dass es solche Source maps zum verwendeten Code gibt, indem man in den Debugger-Einstellungen (Zahnrad-Icon oben rechts) auf "Originalquellen anzeigen" klickt ("Show original sources"):Damit das funktioniert, muss man in der Quelldatei eine Mapping-URL in einem Kommentar angegeben haben, der dem Debugger sagt, wo sich die alternativen Dateien befinden. Ein solcher Kommentar in der JavaScript-Datei sollte folgendermaßen aussehen:

//@ sourceMappingURL=http://example.com/path/to/your/sourcemap.map

Variablenwerte prüfen

Wenn der Debugger an einem Haltepunkt ("breakpoint") die Programm-Ausführung unterbricht, kann man sich die aktuellen Werte der Variablen an dieser Stelle im Code ansehen. Sie werden rechts in der Variablenliste angezeigt:

Rechts befindet sich die Variablenliste. Die Variablen werden in Blöcken nach Geltungsbereichen ("scopes") gefiltert angezeigt. Obje können ausgeklappt werden, wenn man einzelne Eigenschaften sehen möchte (siehe Variablenwerte oben). Auch über ein "*" am Beginn des Skriptsuche-Eingabefelds ("filter expression") kann die Anzeige der Variablen gefiltert werden:

Variablen andere Werte zuweisen

Wenn die Ausführung des Codes an einem Breakpoint ("Haltepunkt") unterbrochen wurde, können die Werte in der Variablenanzeige des Debuggers verändert werden. Einfach auf den aktuellen Variablenwert klicken - der Wert wird zu einem Eingabefeld und kann sofort geändert werden:

Watch an expression

You can watch the value of a JavaScript expression using the "Add watch expression" function in the variables pane.

Debug mobile devices

To learn how to debug mobile devices, see the guide to remote debugging.

Verstecken von Quelldateien ("Black boxing")

Viele Webseiten und Programme nutzen heute Frameworks wie jQuery, Ember oder Angular und zu 99% kann man einfach davon ausgehen, dass deren Code funktioniert. Die Interna dieser Bibliotheken wollen wir beim Debuggen meistens nicht sehen - wir verstecken sie und behandeln sie als Black box. Durch Black boxing entfällt das leidige Eintauchen in Bibliothek-Dateien (zum Beispiel bei each-Schleifen oder dem Auslösen von Events) und wir können uns auf unseren eigentlichen Code konzentrieren.

How to blackbox a source

Black boxing kann auch man für einzelne Dateien ein- und ausschalten, indem man auf das Breakpoint-Symbol ("eyeball": Augapfel) links neben der Quelldatei in der Liste klickt. Viele Quellen können auch versteckt werden, indem man in der Entwickler-Toolbar (Shift + F2) den blackbox-Befehl benutzt:

Wenn eine Code-Datei versteckt ist:

  • ... werden alle Haltepunkte in dieser Quelldatei deaktiviert.
  • ... lässt der Debugger diesen Code auch beim schrittweisen Durchlaufen des Codes ("stepping") aus.
  • Wenn "Unterbrechung bei Exceptions" ("pause on exceptions") eingeschaltet ist, hält der Debugger nicht an, wenn ein Fehler in einer versteckten ("black boxed") Quelldatei geworfen wird - stattdessen wartet er, bis (und: ob) er in der Aufrufliste ("call stack") an einen nicht versteckten Punkt zurück kommt.

Access debugging in add-ons

The following items are accessible in the context of chrome://browser/content/debugger.xul (or, in version 23 beta, chrome://browser/content/devtools/debugger.xul):

  • window.addEventListener("Debugger:EditorLoaded") - called when the read-only script panel loaded.
  • window.addEventListener("Debugger:EditorUnloaded")

Relevant files:

  • chrome://browser/content/devtools/debugger-controller.js
  • chrome://browser/content/devtools/debugger-toolbar.js
  • chrome://browser/content/devtools/debugger-view.js
  • chrome://browser/content/devtools/debugger-panes.js

Unfortunately there is not yet any API to evaluate watches/expressions within the debugged scope, or highlight elements on the page that are referenced as variables in the debugged scope. (currently a work in progress, see bug 653545.)

See also

Schlagwörter des Dokuments und Mitwirkende

Mitwirkende an dieser Seite: Andi21, achimbode, Nostra, fscholz, Hecky77, AngelSankturio, isoewa, hexefatale
Zuletzt aktualisiert von: Andi21,