DOUG LLOYD: Alle Rechte GDB. Was ist das genau? So GDB, der steht für den GNU Debugger, ist ein wirklich genial Werkzeug, das wir können nutzen, um uns zu helfen, unsere Programme zu debuggen, oder herausfinden, wo die Dinge sind falsch in unseren Programmen. GDB ist unglaublich mächtig, aber der Ausgang und die Interaktion mit ihm kann ein wenig kryptisch sein. Es ist in der Regel ein Kommandozeilen-Tool, und es kann eine Menge von Nachrichten auf dich werfen. Und es kann ziemlich schwer zu analysieren genau, was los ist. Glücklicherweise haben wir genommen haben Schritte , dieses Problem für Sie zu beheben wie Sie arbeiten durch CS50. Wenn Sie nicht über die grafische Debugger, die mein Kollege Dan Armandarse hat recht gesprochen ein wenig über in ein Video, sollte hier sein, gerade jetzt, die Sie benötigen um diese Befehlszeile verwenden Werkzeuge, um mit GDB zu arbeiten. Wenn Sie in der CS50 Arbeits IDE, brauchen Sie nicht, dies zu tun. Aber wenn Sie nicht Arbeiten in der CS50 IDE, vielleicht eine Version der CS50 Appliance, oder eine andere Linux-Betriebs System mit GDB installiert ist, Sie benötigen, um zu verwenden Diese Kommandozeilen-Tools. Und da Sie vielleicht haben, das zu tun, es ist nützlich, nur zu verstehen, wie GDB funktioniert über die Befehlszeile. Aber noch einmal, wenn Sie mit dem CS50-IDE, Sie können die grafischen Debugger verwenden dass in den IDE gebaut. Also um Dinge geht mit GDB, um das Debugging zu starten Verfahren nach einem bestimmten Programm, alles, was Sie tun müssen, ist Typ GDB gefolgt nach dem Programmnamen. So zum Beispiel, wenn Ihr Programm hallo, würden Sie GDB hallo geben. Wenn du das tust, wirst du zu ziehen Sie die GDB Umwelt. Prompt wird sich ändern, und statt, was es normalerweise ist, wenn man die Dinge geben an den Befehl ls line--, cd-- alle Ihre typischen Linux-Befehle, Ihre prompte wird, wahrscheinlich, etwas zu ändern wie Klammern GDB Klammern. Das ist Ihr neues GDB Aufforderung, weil Sie innerhalb der GDB-Umgebung sind. Einmal in dieser Umgebung, es gibt zwei wichtige Befehle dass Sie wahrscheinlich verwenden in dieser Reihenfolge. Die erste ist B, die ist die Abkürzung für Pause. Und nachdem Sie Typ B, Sie in der Regel Geben Sie den Namen einer Funktion, oder wenn Sie weiß zufällig, um das, was Zeilennummer Ihr Programm wird gestartet verhalten ein wenig seltsam, Sie eine Zeile eingeben können Nummer auch dort. Was für b oder Pause tut ist es erlaubt Ihrem Programm In den Hochlauf bis zu einem bestimmten Punkt, nämlich den Namen der Funktion, dass Sie angeben, oder die Leitung Zahl, die Sie angeben. Und an diesem Punkt ist es, wird die Ausführung einzufrieren. Dies ist eine wirklich gute Sache, denn einmal die Ausführung eingefroren wurde, Sie können sehr langsam beginnen Schritt für Schritt durch das Programm. In der Regel, wenn Sie waren läuft Ihre Programme, sie sind ziemlich kurz. Normalerweise dot Schrägstrich geben Sie unabhängig der Name des Programms, drücken Sie die Eingabetaste, und bevor Sie blinken kann, Ihrem Programm bereits beendet. Es ist nicht wirklich viel Zeit, um zu versuchen und herauszufinden, was falsch läuft. So dass es wirklich in der Lage, die Dinge zu verlangsamen nach unten, indem Sie einen Haltepunkt mit b, und dann verstärkt in. Dann, wenn Sie Ihre Pause festgelegt haben Nun können Sie das Programm auszuführen. Und wenn Sie welche haben Befehlszeilenargumente, Sie sie hier angeben, nicht, wenn Sie tippen GDB Ihren Programmnamen. Sie legen fest, alle in der Befehlszeile Argumente, indem r, oder laufen, und dann unabhängig von Befehlszeilenargumente Sie brauchen innerhalb Ihres Programms. Es gibt eine Anzahl von anderen wirklich wichtige und nützliche Befehle Innere des BIP Umwelt. Also lassen Sie mich nur schnell gehen Sie über einige von ihnen. Die erste n ist, die Kurzform für nächsten ist, und man kann weiter anstelle von n-Typ, beide funktionieren würde. Und es ist nur die Kurzform. Und wie Sie wahrscheinlich schon bekommen um, in der Lage, Dinge zu geben verwendet kürzer ist im allgemeinen besser. Und was sie tun werden, ist, es wird Schritt nach vorn einen Code-Block. So dass es dann vorwärts zu bewegen bis zu einem Funktionsaufruf. Und dann statt Tauchen in dieser Funktion und gehen durch alle dieser Funktionen Code, wird es nur die Funktion haben. Die Funktion wird aufgerufen. Es wird alles tun, was ihre Arbeit ist. Es wird ein Wert zurück die Funktion, die sie aufruft. Und dann wirst du gehen Sie zum nächste Zeile dieser aufrufenden Funktion. Wenn Sie mit Schritt wollen innerhalb der Funktion, statt nur mit sie auszuführen, vor allem wenn Sie denken, dass das Problem könnte innerhalb dieser Funktion liegen, Sie könnten natürlich, setzen Sie eine Pause Punkt innerhalb dieser Funktion. Oder wenn Sie bereits ausgeführt sind, können Sie benutzen s nach vorne eine Zeile Code zu treten. So wird dies in Schritt und tauchen Sie in Funktionen, anstatt einfach nur die Ausführungs und Weiterbildung von in der Funktion dass Sie in der Fehlersuche. Wenn Sie überhaupt wissen wollen der Wert einer Variablen, Sie tippen können p oder drucken, und dann der Variablenname. Und das wird sich um Sie zu drucken, Innenseite der GDB Umgebung der Name der Variable, dass Sie-- entschuldigen Sie mich- den Wert der Variablen dass Sie noch benannt. Wenn Sie die Werte jeder wissen wollen lokalen Variablen zugänglich, von wo aus Sie derzeit in Ihrem Programm können Sie Informationen Einheimische geben. Es ist viel schneller als drücken Sie p und dann was auch immer, Listing out all die Variablen, die Sie wissen, existieren. Sie können Informationen Einheimische geben, und es wird für Sie ausdrucken alles. Als nächstes ist bt, das ist kurz für zurückzuverfolgen. Jetzt im Allgemeinen besonders früh in CS50, Sie werden nicht wirklich Anlass um bt oder Zurück Trace verwenden, denn Sie sind nicht mit Funktionen dass andere Funktionen aufrufen. Sie könnten Haupt Call a haben Funktion, aber das ist wahrscheinlich es. Sie müssen nicht, dass andere Funktion Aufruf einer anderen Funktion, die eine andere Funktion aufruft, und so weiter. Aber wie Sie Ihre Programme erhalten mehr Komplex, und insbesondere wenn Sie mit der Arbeit beginnen mit Rekursion zurückSpuren kann eine wirklich nützliche Methode, um Sie lassen Art bekommen einige Kontext, wo Ich bin in meinem Programm. So sagen Sie Ihren Code geschrieben haben, und Sie wissen, dass Haupt ruft eine Funktion f, die eine Funktion aufruft g, das eine Funktion h aufruft. So haben wir mehrere Schichten der Verschachtelung hier los ist. Wenn Sie innerhalb bist Ihre GDB Umwelt, und Sie haben Ihre innen kennen von h, aber Sie vergessen, über das, was du hast, wo Sie sind-- können Sie bt oder Rückverfolgung geben, und es wird aus h, g zu drucken, f Haupt, neben einigen anderen Informationen, die gibt Ihnen einen Hinweis darauf, dass, OK Haupt genannt f, f genannte g, g genannte h, und das ist, wo ich derzeit bin in meinem Programm. So kann es sehr nützlich sein, zumal die kryptischen-ness der GDB wird ein wenig überwältigend, um genau herauszufinden, wo die Dinge sind. Schließlich, wenn Ihr Programm fertig ist, oder wenn Sie fertig sind Debuggen und Sie Schritt weg möchten von der GDB-Umgebung, Es hilft zu wissen, wie man aus ihm herausholen. Sie können geben Sie q, oder Beenden, um aus. Jetzt, vor der heutigen Video Ich ein fehlerhaftes Programm vorbereitet genannt buggy1, die ich zusammengestellt aus einer Datei als buggy1.c bekannt. Wie Sie vielleicht erwarten, dass diese Programm ist in der Tat fehlerhaft. Etwas schief geht wenn ich versuche, und führen Sie es. Nun, leider, ich versehentlich gelöscht meine buggy1.c-Datei, so in Ordnung für mich, um herauszufinden, was falsch läuft mit diesem Programm, Ich werde verwenden zu müssen GDB Art von blind, versuchen um durch dieses Programm zu navigieren genau herauszufinden, was falsch läuft. Aber mit nur die Werkzeuge, haben wir bereits kennen gelernt haben, wir können ziemlich Figur herauszufinden, was genau es ist. Lassen Sie uns also über Kopf zu CS50 IDE und haben einen Blick. OK, so dass wir hier in meinem CS50 IDE-Umgebung, und ich werde in ein wenig zu vergrößern so können Sie ein wenig mehr zu sehen. In meinem Terminal-Fenster, wenn ich Liste der Inhalt meiner derzeitigen Direktor mit ls, werden wir, die ich sehe haben ein paar Quelldateien hier, einschließlich der zuvor diskutiert buggy1. Was genau passiert, wenn Ich versuche und laufen buggy1. Nun lassen Sie uns herausfinden. Ich tippe dot Schrägstrich, buggy, und ich drücken Sie Enter. Segmentation Faults. Das ist nicht gut. Wenn Sie sich erinnern, ein Segmentation Fault in der Regel tritt auf, wenn wir Zugang zu Speicher dass wir uns nicht erlaubt zu berühren. Wir haben irgendwie erreicht außerhalb der Grenzen was das Programm, das Compiler, uns gegeben hat. Und so schon das ist eine Anhaltspunkt in der Toolbox zu halten wie wir beginnen den Debugging-Prozess. Etwas hat sich hier ein wenig schief gegangen. In Ordnung, also lassen Sie uns Start up der GDB-Umgebung und sehen, ob wir herausfinden können was genau das Problem ist. Ich werde meinen Bildschirm zu löschen, und ich werde geben GDB einmal, um die GDB Umwelt gelangen, und der Name des Programms, dass ich zu debuggen, buggy1. Wir bekommen eine kleine Nachricht, Lesen Symbole aus buggy1, fertig. Alles, was bedeutet, es ist gezogen zusammen den gesamten Code, und jetzt ist es in geladen wurde GDB, und es ist bereit zu gehen. Nun, was soll ich tun will? Haben Sie, was der Rückruf ersten Schritt typischerweise nachdem ich bin in dieser Umgebung? Ich hoffe, die Sie gesetzt einen Haltepunkt, denn in der Tat das ist, was ich tun möchte. Nun, ich habe nicht die Quellcode für diese vor mir, das ist wahrscheinlich nicht der typische Anwendungsfall, von der Art und Weise. Sie werden wahrscheinlich. Also das ist gut. Aber angenommen, Sie tun nicht, was ist die eine Funktion, die Sie wissen, existiert in jedem einzelnen C-Programm? Egal wie groß oder wie kompliziert sie ist, existiert diese Funktion auf jeden Fall. Main, nicht wahr? So andernfalls alles andere, können wir einen Haltepunkt am wichtigsten. Und wieder, ich geben könnte brechen Haupt statt b. Und wenn Sie neugierig, wenn Sie überhaupt geben Sie einen langen Befehl und dann feststellen, dass Sie typisiert die falsche Sache, und Sie loszuwerden möchten vor allem als ich gerade tat, Sie können steuern, U zu nehmen, die wird löschen alles und bringen Sie zurück zu Beginn der Cursorlinien. Viel schneller als Halten Sie einfach die löschen oder schlagen sie ein Bündel Zeiten über. Also werden wir einen Haltepunkt am Haupt gesetzt. Und wie Sie sehen können, heißt es, wir haben einen Haltepunkt an Datei buggy1.c, und anscheinend die erste Zeile der Code der Hauptlinie ist sieben. Auch hier haben wir nicht Hier die Quelldatei, aber ich gehe davon aus, dass es sagen mir die Wahrheit. Und dann, ich versuche nur, und führen Sie das Programm, r. Startprogramm. In Ordnung, so dass diese Nachricht ist ein wenig kryptisch. Aber im Grunde, was ist hier passiert, ist, es ist nur, sagen mir, ich habe meine Pause traf Punkt, Bruchstelle Nummer 1. Und dann, dass Code-Zeile, Keine solche Datei oder Verzeichnis. Der einzige Grund, Ich sehe diese Nachricht ist, weil ich aus Versehen gelöscht meine buggy.c Datei. Wenn meine buggy1.c Datei existiert im aktuellen Verzeichnis, diese Linie genau dort würde tatsächlich sagen Sie mir, was die Codezeile wörtlich liest. Leider gelöscht ich es. Wir gehen zu müssen, um Art zu navigieren durch diese ein wenig mehr blind. OK, also lassen Sie uns sehen, was will ich hier tun? Nun, ich würde gerne wissen, was vor Ort Variablen vielleicht stehen mir zur Verfügung. Ich habe mein Programm gestartet. Mal sehen, was sein könnte bereits für uns initialisiert. Ich tippe Info Einheimischen, keine Einheimischen. In Ordnung, so dass nicht geben Sie mir eine Tonne von Informationen. Ich könnte versuchen, und drucken Sie eine variable, aber ich kenne keine Variablennamen. Ich könnte eine Rückverfolgung zu versuchen, aber ich bin im Inneren des Haupt, damit ich weiß, habe ich nicht gemacht ein anderer Funktionsaufruf jetzt. So sieht aus wie meine einzige Optionen n oder so verwenden und starten Sie zu tauchen. Ich werde n verwenden. Also ich schreibe n. Oh mein Gott, was ist denn hier los. Programm empfangenen Signale, SIGSEGV Segmentation Fault, und dann eine ganze Reihe von Sachen. Ich bin schon überfordert. Nun, es ist eigentlich ein Menge zu lernen. Also, was sagt uns das? Was es uns sagt, ist, dieses Programm dabei, hat aber noch nicht, seg Fehler. Und vor allem werde ich in noch weiter hier zu vergrößern, es geht um den Fehler zu seg so etwas wie strcmp. Nun, können wir nicht diskutiert haben diese Funktion ausgiebig. Aber es ist-- denn wir werden nicht zu sprechen über jede Funktion, gibt es in der C-Standard library-- aber sie sind alle zu Ihnen zur Verfügung, insbesondere, wenn Sie nehmen ein Blick auf reference.cs50.net. Und strcmp ist ein wirklich leistungsfähiges Funktion, die im Inneren vorhanden ist der Header string.h Datei, die einen Header Datei, die auf Funktionen gewidmet ist , dass die Arbeit mit und zu manipulieren Strings. Und vor allem, was tut, ist strcmp Es vergleicht die Werte der zwei Strings. Also ich bin zu Fehler Segmentierung bei einem Aufruf an strcmp es scheint. Ich schlug n, und in der Tat bekomme ich die Meldung, Programm mit Signal SIGSEGV beendet Segmentation Fault. So jetzt Ich habe eigentlich seg bemängelt, und mein Programm hat ziemlich sehr effektiv aufgegeben. Dies ist das Ende des Programms. Er brach zusammen, stürzte sie. So war nicht viel, aber ich tatsächlich lernen einiges aus dieser wenig Erfahrung. Was habe ich gelernt? Nun, stürzt mein Programm so ziemlich sofort. Mein Programm stürzt auf Ein Anruf bei strcmp, aber ich keine lokalen Variablen in meine Programm an der Zeit, dass es abstürzt. Also, welche Zeichenfolge oder Zeichenfolgen, könnte ich den Vergleich sein. Wenn ich habe keine lokalen Variablen, können Sie vermuten, dass ich dort have-- vielleicht ein globale Variable, die wahr sein könnte. Aber im allgemeinen scheint es wie ich bin zu vergleichen , etwas, das nicht existiert. Also lassen Sie uns untersuchen, daß ein wenig weiter. Also werde ich zu meinem Bildschirm zu löschen. Ich werde von der beenden GDB-Umgebung für eine Sekunde. Und ich denke, OK, es gibt also keine lokalen Variablen in meinem Programm. Ich frage mich, ob vielleicht soll ich weitergeben in einem String als Befehlszeilenargument. Lassen Sie uns also nur zu testen dies. Ich habe nicht getan. Mal sehen, ob vielleicht, wenn ich dieses Programm mit einem Kommandozeilenargument es funktioniert. Huh, keine Segmentation Fault gibt. Er sagte mir nur, dass ich es herausgefunden. Also vielleicht ist das das Update hier. Und in der Tat, wenn ich gehen Sie zurück und betrachten der eigentliche Quellcode für buggy1.c, es scheint, als ob das, was ich tue, ist Ich mache einen Anruf an, ohne strcmp Prüfen, ob in der Tat argv [1] existiert. Dies tatsächlich die Quellcode für buggy1.c. Also, was ich wirklich brauchen, um tun Sie hier, um mein Programm zu beheben, vorausgesetzt, ich habe die Datei vor mir ist fügen Sie einfach einen Scheck zu machen Sie sicher, dass argc gleich 2. So ist dieses Beispiel noch einmal, wie ich schon sagte, ist ein wenig gekünstelt, nicht wahr? Sie sind in der Regel nicht zu gehen Versehen Sie Ihre Source-Code zu löschen und müssen dann versuchen, und Debuggen des Programms. Aber hoffentlich, es gab Sie eine Illustration der Arten von Dingen, Sie könnte zu denken, wie Sie das Debugging Ihres Programms sind. Was ist der Stand der Dinge hier? Welche Variablen muss ich müssen zugänglich bleiben? Wo genau ist mein Programm Absturz, auf welcher Linie, auf welchem ​​Aufruf an welche Funktion? Welche Art von Hinweisen nicht, dass mir geben? Und das ist genau das Art der Denkweise, dass Sie sollte immer sein, wenn Sie in die Nachdenken über das Debugging Ihrer Programme. Ich bin Doug Lloyd. Dies ist CS50.