it-swarm.com.de

Was bringt es, die Verwendung eines Debuggers zu vermeiden?

Im Laufe meiner Karriere habe ich festgestellt, dass einige Entwickler keine Debugging-Tools verwenden, sondern fehlerhaften Code vor Ort überprüfen, um herauszufinden, wo das Problem liegt.

Obwohl es oft eine gute Fähigkeit ist, Fehler im Code ohne Debugger schnell zu finden, scheint es weniger produktiv zu sein, viel Zeit damit zu verbringen, nach Problemen zu suchen, bei denen ein Debugger leicht kleine Fehler wie Tippfehler finden würde.

Ist es möglich, einen Komplex ohne Debugger zu verwalten? Ist es ratsam? Welche Vorteile bietet die Verwendung von " psychisches Debugging ?"

102

Was von außen so aussieht, als würde man raten, entpuppt sich oft als das, was ich "Debugging in deinem Kopf" nenne. In gewisser Weise ähnelt dies der Fähigkeit der Großmeister, Schach zu spielen, ohne auf ein Schachbrett zu schauen.

Es ist bei weitem die effizienteste Debugging-Technik, die ich kenne, da es überhaupt keinen Debugger erfordert. Ihr Gehirn untersucht mehrere Codepfade gleichzeitig und erzielt so einen besseren Turnaround als mit einem Debugger.

Ich war mir dieser Technik nicht bewusst, bevor ich kurz in die Welt von wettbewerbsfähige Programmierung eintrat, wo die Verwendung eines Debuggers den Verlust wertvoller Sekunden bedeutete. Nach ungefähr einem Jahr im Wettbewerb begann ich, diese Technik fast ausschließlich als meine erste Verteidigungslinie zu verwenden, gefolgt von der Debug-Protokollierung, wobei ein tatsächlicher Debugger auf dem entfernten dritten Platz saß. Ein nützlicher Nebeneffekt dieser Vorgehensweise war, dass ich langsamer neue Fehler hinzufügte, da das "Debuggen in meinem Kopf" nicht aufhörte, als ich neuen Code schrieb.

Natürlich hat diese Methode ihre Grenzen, hauptsächlich aufgrund der Einschränkungen des eigenen Verstandes bei der Visualisierung mehrerer Pfade durch den Code. Ich lernte, diese Einschränkungen meines Geistes zu respektieren und wandte mich an einen Debugger, um Fehler in fortgeschritteneren Algorithmen zu beheben.

153
dasblinkenlight

Je mehr ich über eine Codebasis weiß, desto weniger brauche ich einen Debugger (aber ich würde den gemeldeten Fehler trotzdem überprüfen, es ist ein wichtiger Hinweis in jeder Argumentation).

Es ist ein gutes Werkzeug, um ein dynamisches Verhalten von kleiner bis mittlerer Komplexität zu verstehen, aber ich stelle oft fest, dass es mich auf die Details anstatt auf das Gesamtbild konzentriert. Und nach einer Weile liegen hier die Probleme: In einem größeren Bereich sind Interaktionen, deren dynamisches Verhalten mit anderen Tools leichter verständlich ist (z. B. Protokollierung von Ein- und Ausgaben an Modulgrenzen).

41
AProgrammer

Sie sind vielleicht keine schlechten Programmierer, aber sie sind wahrscheinlich schrecklich ineffiziente Problemlöser.

Ich neige dazu, den Ratschlägen von Debugging: Die 9 unverzichtbaren Regeln, um selbst die schwer fassbaren Software- und Hardwareprobleme zu finden (David Agans) zu folgen, und dieser fällt direkt unter die Anleitung von "Denken und schauen aufhören".

35
JohnFx

Für jeden Job müssen die richtigen Werkzeuge richtig eingesetzt werden. Wenn Sie einen Debugger haben, verwenden Sie ihn, um zu sehen, was tatsächlich passiert. Die meisten Fehler werden durch Annahmen verursacht.

Ich habe mit Entwicklern zusammengearbeitet, die sich weigern, Debugger zu verwenden, weil sie es besser wussten. Die klassische Antwort, die ich einmal erhielt, war: "Der Absturz wird nicht von mir verursacht. Ich habe den ganzen Tag damit verbracht, den Code zu überprüfen [wo er abgestürzt ist], und es ist nichts falsch." (Was ist mit dem Nullwert, der von der Datenbank eingelesen wurde?) Der Chef schien zu denken, dass es eine großartige Antwort war, aber der Kunde tat es nicht.

Ich bin so schnell ich konnte aus dem Team ausgestiegen. Ihr Ziel war es, den Job zu verbessern und aus einem einfachen 10-Minuten-Problem ein ganztägig beschäftigtes Problem zu machen.

31
jqa

Ihr bester Leitfaden für das Debuggen ist Steve McConnels Buch Code Complete. Kapitel 23 behandelt das Debuggen im Detail, und ich werde einige Punkte daraus herausarbeiten.

  1. Das Verständnis des Problems ist wichtig, und die Verwendung des Debuggers ist kein Ersatz dafür.
  2. Raten ist ein schlechter Ansatz zum Debuggen. Wenn Ihre Kollegen wirklich Vermutungen anstellen, anstatt über das Problem nachzudenken, machen sie einen schlechten Job. Vermutungen bedeuten, zufällige Druckanweisungen in den Code zu stecken und zu hoffen, etwas Nützliches zu finden.
  3. Wenn Ihre Kollegen wirklich nicht wissen, wie man einen Debugger verwendet (anstatt sich dafür zu entscheiden, keinen zu verwenden), sind sie inkompetent, genau wie jemand, der die Syntax der Sprache, die sie verwenden sollen, nicht kennt.
13
DJClayworth

Ich bin überrascht, dass in der Diskussion zu diesem Thema "Unit Testing" nicht erwähnt wurde.

Da ich testgetrieben entwickle, verbringe ich nicht viel Zeit im Debugger. Vor 10 Jahren habe ich den Debugger pflichtbewusst durchlaufen:

  1. Nach dem Schreiben eines Codes, um sicherzustellen, dass es funktioniert und
  2. Als ich einen Fehlerbericht erhielt, um zu versuchen, das Problem zu diagnostizieren

Was ich nach 10 Jahren testgetriebener Entwicklung festgestellt habe, ist, dass ich als Programmierer viel produktiver bin, wenn:

  1. Ich schreibe Unit-Tests vorher Ich schreibe den Code, um sicherzustellen, dass ich ihn richtig geschrieben habe
  2. Ich schreibe Unit-Tests sofort nach Erhalt eines Fehlerberichts, um zu versuchen, das Problem zu duplizieren und einen Drilldown durchzuführen.

Das Zulassen, dass der Computer den Code durchläuft und das Ergebnis validiert, ist tausende Male schneller, als ich denken oder durch den Code gehen kann, um die Ergebnisse mental zu validieren, und macht keine Fehler.

Ich muss immer noch gelegentlich im Debugger durchgehen und bin immer noch damit beschäftigt, den Code mental zu analysieren ... aber nur selten und meistens für sehr kniffligen Code.

9
Jeff Grover

Schwer zu erzählen. Das Debuggen durch Erraten könnte funktioniert, wenn Sie bereits eine Vorstellung davon haben, was der Fehler ist (falscher Wert, der an eine Bibliotheksfunktion übergeben wird, möglicherweise ungültiges SQL usw.). Ich gebe zu, dass ich es manchmal mache, wenn der Fehler selbst klein oder offensichtlich erscheint, wie z. B. "Zeichenpuffer zu klein" - der Stack-Trace zeigt mir die Zeile, in der er fehlgeschlagen ist, und ich brauche keinen Debugger, um diesen Fehler zu beheben.

Dies zu tun die ganze Zeit kann kontraproduktiv sein und wenn die ersten "Vermutungen" fehlschlagen, ist das Erraten wahrscheinlich die falsche Strategie zur Problemlösung und ein echter Debugger sollte hinzugezogen werden. Normalerweise würde ich sagen, dass es das gibt absolut nichts falsch mit dem Debugger.

Davon abgesehen habe ich mit Tools und Umgebungen gearbeitet, in denen es so schwierig war, den Debugger richtig zum Laufen zu bringen, oder so minimal und nutzlos, dass das Erraten leider oft ein besserer Ansatz war. Ich habe mit einigen proprietären Tools gearbeitet, die nicht einmal die richtigen Debugger hatten. Ich nehme an, es ist möglich, dass eine Person, die zu lange in solchen Umgebungen gearbeitet hat, irgendwann das Vertrauen in Debugger verliert und sich nur noch auf den Schätzungsansatz verlässt.

Persönlich versuche ich, die Verwendung eines Debuggers zu minimieren, indem ich:

  • verwenden von statische Prüfer und ähnlichen Compileroptionen, die durch Analyse des Codes auf mögliche Fehlerquellen hinweisen
  • schreiben von Code mit as wenige Nebenwirkungen wie möglich, in einem möglichst funktionalen Stil, wobei der veränderliche Zustand nach Möglichkeit beseitigt wird
  • schreiben nit-Tests mit minimaler vernünftiger Granularität
  • ausnahmen nicht schlucken

Natürlich macht jeder Fehler. Selbst wenn ein Test auf diese Weise erstellt wird und ein Test fehlschlägt, verwende ich den Debugger, um den Wert eines Zwischenausdrucks zu überprüfen. Durch die Einhaltung der oben genannten Grundsätze ist der Fehler jedoch leichter zu lokalisieren, und das Debuggen bedeutet keinen schmerzhaften, unbestimmten Prozess.

8
thSoft

Verwenden Sie den Debugger, wann immer dies möglich ist. Der Debugger wird entweder einfach das Problem lösen (oh, wir haben diesen Wert nicht überprüft) oder eine Menge Kontext bereitstellen, der bei der Analyse des relevanten Codes nützlich ist (wow, der Stapel ist total durcheinander, werde ich sei es ein Pufferüberlaufproblem).

6
Kevin Hsu

Das Debuggen ist ein sehr nützliches Werkzeug, um den Status der Objekte und Variablen in Ihrem Code zur Laufzeit zu überprüfen.

Wie bereits in den obigen Antworten erwähnt, ist das Debuggen äußerst hilfreich, in einigen Fällen ist es jedoch begrenzt.

Nach meiner Erfahrung ist die Verwendung des Debuggers sehr nützlich, da dadurch falsche Annahmen über den Status meines Codes aufgedeckt werden können. Einige Leute sind nicht so geschickt darin, den Code zu lesen, um einen Fehler zu finden. Daher kann das Debuggen dazu beitragen, falsche Annahmen aufzudecken, die Sie oder ein anderer Entwickler über den Status des Codes gemacht haben.

Vielleicht erwarten Sie, dass ein Parameter niemals null sein wird, wenn er an eine Methode übergeben wird, also prüfen Sie niemals diesen Fall und fahren in der Methode fort, als ob dieser Parameter niemals null sein wird. Die Realität ist, dass der Parameter will irgendwann null ist, selbst wenn Sie als Voraussetzung für die Methode festlegen, dass der Parameter niemals null sein sollte. Es wird immer passieren.

Im Gegensatz zur Nützlichkeit von Debuggern in den oben genannten Beispielen finde ich es schwierig und etwas nicht nützlich, wenn Multithreading (d. H. Parallelität, asynchrone Verarbeitung) verwendet wird. Es kann helfen, aber es ist leicht, die Orientierung im Multithread-Nebel zu verlieren, wenn die Haltepunkte des Debuggers in einem Thread an Punkt A und einem vollständig separaten Thread an Punkt B getroffen werden. Der Entwickler ist gezwungen, den neuen Haltepunkt zu verschieben. " Denkprozess "oben auf dem" Stapel "seines Gehirns und orientieren Sie sich am Code am Punkt des neuen Haltepunkts. Nachdem die Relevanz von Haltepunkt B abgenommen hat, wechselt der Entwickler zurück zum ersten Haltepunkt und muss sich daran erinnern, wonach er/sie vor dem Auslösen von Haltepunkt B gesucht hat. Ich weiß, dass dies eine verwirrende Erklärung sein kann, aber mein Punkt In diesem Absatz wird das Debuggen bei gleichzeitiger Verwendung als sehr ADD bezeichnet (Attention Deficit Disorder) -Prozess, und daher kann es schwieriger sein, in Ihrem Debugging-Gedankenmuster produktiv zu bleiben.

Auch die Unvorhersehbarkeit von gleichzeitigem Code kann den Entwickler beim Debuggen von gleichzeitigem Code weiter ablenken.

Abschließend meiner ehrlichen Meinung nach:

  • Debuggen bei gleichzeitiger Verwendung = erhöhte Tendenz, den Fokus des "Debuggens von Gedankenmustern" zu verlieren

und

  • jederzeit anders = erhöhte Debugging-Produktivität b/c Ihre Aufmerksamkeit wird nicht durch unerwartete Haltepunkte unterbrochen (unerwartet aufgrund der Rennbedingungen).
5
BigSauce

Ich denke, sie sind ein bisschen zu hardcore. Wenn ich persönlich auf einen Fehler stoße, überprüfe ich den Code erneut und versuche, ihn in meinem Kopf anhand der Programmlogik zu verfolgen, da dies mir manchmal hilft, andere Probleme oder Nebenwirkungen einfacher aufzudecken, als nur den Debbuger zu verwenden und den Fehler dort zu beheben, wo er sich manifestiert .

Selbst wenn ich denke, dass ich es geschafft habe, debugge ich es normalerweise, um sicherzugehen, dass ich Recht habe. Wenn das Problem etwas komplexer ist, halte ich das Debuggen für absolut notwendig.

Auch ... nur meine Meinung, aber es gibt keine Entschuldigung dafür, die Werkzeuge, die ein modernes IDE] auf den Tisch bringen kann, nicht angemessen zu nutzen. Wenn es Ihnen hilft, Ihre Arbeit schneller und schneller zu erledigen Ein zuverlässigerer Weg, sollten Sie es verwenden.

4
pcalcao

Ich hasse es zu verallgemeinern, aber viele Programmierer, die ich getroffen habe, glauben, dass es nur einen Weg gibt, ein Problem zu lösen (ihren Weg). Es ist leicht anzunehmen, dass an jeden möglichen Test gedacht wurde. Eine andere Perspektive kann sehr wertvoll sein.

Das Programmieren durch Ausprobieren kann einige großartige neue Ansätze hervorbringen und Dinge erfassen, die andere übersehen haben.

Der Nachteil dauert normalerweise viel länger.

4
user977645

Ähm, es kommt auf die Person an. Persönlich benutze ich selbst nicht so viele Debugger. Wenn ich Mikrocontroller programmiere, verwende ich grundsätzlich LEDs oder schreibe Daten in EEPROMs, um den darauf befindlichen Code zu "debuggen". Ich benutze kein JTAG.

Wenn ich Software für PCs oder Server programmiere, verwende ich normalerweise Protokollierung und viele Konsolenausgaben. Für Sprachen im C-Stil verwende ich Präprozessor-Direktiven und in Java habe ich Protokollebenen verwendet.

Würden Sie sagen, dass ich etwas falsch mache, da ich keine Debugger verwende? Es sind die Editoren-Jobs, um mir zu zeigen, wo ich syntaktische Fehler habe, und wenn es einen logischen Fehler gibt, muss ich nur Tests ausführen.

4
polemon

Es gibt einen Unterschied zwischen der Notwendigkeit, keinen Debugger zu verwenden, und dem Wissen, wie man einen Debugger verwendet (oder ablehnt). Der Debugger ist nur eines von vielen Tools zum Verfolgen und Beheben von Fehlern. Ich habe mit Entwicklern zusammengearbeitet, die es in ihrem Kopf rätseln können, und mit anderen, die glauben, dass sie es können.

Die beste Mischung besteht darin, Ihren Code so zu schreiben, dass er einfach über Unit-Tests getestet und die Fehler protokolliert werden können. Dann hoffen Sie, dass Sie nicht in die Protokolle schauen oder den Debugger verwenden müssen. Es ist wie ein Versicherungskauf. Sie müssen es hoffentlich nie verwenden, aber sobald Sie auf einen Fehler stoßen, der nicht durch erneutes Überprüfen des Codes behoben werden kann, ist es zu spät, eine ordnungsgemäße Fehlerbehandlung/-protokollierung, Komponententests oder die Verwendung eines Debuggers hinzuzufügen.

Verschiedene Tools/Plattformen bevorzugen unterschiedliche Debugging-Techniken (Debugger, Protokollierung, Komponententests usw.). Solange ein Entwickler mit einigen Techniken für seine Plattform/sein Tool vertraut ist, kann es sein, dass er nur den Code erneut überprüft Ein erfahrener Entwickler, aber wenn er nur einen Trick beim Debuggen hat, wird er irgendwann auf einen Fehler stoßen, den er nicht finden oder beheben kann.

4
Jim McKeeth

Viele Antworten, aber keine Erwähnung über Heisenbug ?!?!

Heisenbugs treten auf, weil häufige Versuche, ein Programm zu debuggen, wie das Einfügen von Ausgabeanweisungen oder das Ausführen in einem Debugger, normalerweise den Code ändern, die Speicheradressen von Variablen und den Zeitpunkt seiner Ausführung ändern.

Ich benutze den Debugger nur im schlimmsten Fall (für schwer zu findende Fehler). Gemäß den Best Practices, über die viele anerkannte Entwickler/Tester gesprochen haben, ist es außerdem gut, den Code gründlich zu testen. Auf diese Weise können Sie die meisten Probleme abdecken, sodass der Debugger nicht verwendet werden muss.

4
bchetty

Mit guten Unit-Tests und Ausnahmen, die Ihnen den Backtrace bieten, müssen Sie selten einen Debugger verwenden.

Das letzte Mal, als ich ein Debugging verwendete, war, als ich eine Kerndatei in einer Legacy-Anwendung bekam.

Bin ich ein "Debbuger Minion" oder sind diese Jungs "zu hardcore"?

Weder. Sie sind nur eine Art von Menschen, die ihr Leben gerne schwerer machen, als es sein sollte.

3
BЈовић

Ich habe kürzlich hier ein Argument gegen das Debuggen von Debuggern gelesen (oder war es StackOverflow?). Sie sollten Testfälle gegen Ihren Code haben. Wenn Ihre Tests erfolgreich sind, wird Ihr Debugging den Fehler wahrscheinlich nicht auslösen (Annahme: Sie debuggen mit Daten, die Ihren Testdaten ähnlich sind).

Auf der anderen Seite ist die Protokollierung obligatorisch. Wenn Sie Ihre Tests bestehen und für die Produktion bereitstellen, stellen Sie möglicherweise einen Fehler fest. Der Beweis für den Fehler stammt von etwas, das in der Vergangenheit passiert ist. d.h. jemand sagt: "Wie ist das da reingekommen?" Wenn Sie keine guten Protokolle haben, werden Sie nie die Ursache finden. Selbst ein Debugger kann zu diesem Zeitpunkt möglicherweise nicht von Nutzen sein, da Sie nicht wissen, wie die Daten aussahen, die den Fehler tatsächlich ausgeübt haben. Sie müssen in der Lage sein, die Anwendung aus den Protokollen zu debuggen.

Leider paraphrasiere ich ziemlich viel und mache dem ursprünglichen Argument möglicherweise einen schlechten Dienst. Insbesondere könnte die Position "Es gibt wichtige Debugging-Hilfsmittel, um Entwicklungszeit zu unterstützen" orthogonal zur Bedeutung von Debuggern sein. Aber der Teil über die Schwierigkeit, den Systemstatus in einer Konfiguration festzulegen, die das Debuggen nützlich macht, um Fehler zu finden, kam mir zum Nachdenken.

3
ccoakley

Das Debuggen ist nur ein Werkzeug, das ein guter Entwickler kompetent einsetzen sollte.

Sicherlich können Sie manchmal auswendig wissen, wo der Fehler liegen kann, wenn Sie die Codebasis kennen. Sie können aber auch einen ganzen Tag oder eine ganze Woche verlieren, um einen lästigen Fehler zu finden, indem Sie einfach in den Code schauen.

In dynamisch typisierten Sprachen ohne Debugging (auch wenn nur Werte an die Konsole ausgegeben werden) wird das Erraten manchmal unmöglich.

Um Ihre Frage zu beantworten: Vielleicht sind sie brillante Programmierer, aber ihre Fähigkeiten zur Fehlerbehebung und ihre Fähigkeiten bei der Suche nach Fehlern sind schlecht.

2
Christian P

Kommt auf den Umfang eines Problems an. Wenn das Programm klein ist und die Dinge gut aufgeteilt sind, können Sie es wahrscheinlich durch einen Blick herausfinden. Wenn das Programm aus 4,5 Millionen Codezeilen besteht, die von einem Team von mehr als 100 Mitarbeitern über mehrere Jahre hinweg entwickelt wurden, sind bestimmte Fehler nicht zu erkennen.

Das fragliche in diesem Programm (in C) war ein Speicherüberschreiben. Der Debugger mit einem Speicher-Haltepunkt identifizierte die fehlerhafte Codezeile, sobald der Fehler auftrat. In diesem Fall hätte jedoch niemand alle 4,5 Millionen Codezeilen lesen und beibehalten können, um den einen Punkt zu identifizieren, den jemand hinter seinem Array geschrieben hat (und er hätte das Laufzeitlayout des Speichers für den Status des gigantischen Programms kennen müssen ca. 10 Minuten in eine lange Reihe von Eingaben, um es an diesen Punkt zu bringen).

Punkt ist: In kleinen Programmen oder Dingen, die stark modularisiert sind, können Sie ohne einen Debugger davonkommen. Wenn das Programm wirklich groß und komplex ist, kann der Debugger Ihnen viel Zeit sparen. Wie andere gesagt haben, ist es ein Werkzeug, und es hat Situationen, in denen es sich von jeder anderen Methode abhebt, und andere, in denen es nicht die beste Wahl ist.

2
anon

Wenn der Fehler auf dem Computer eines Clients oder auf einem Computer auftritt, dessen Umgebung sich stark von Ihrer unterscheidet, ist das Einrichten eines Debuggers/Remote-Debuggers umständlich. Für den kalten Tag, an dem Sie einen Fehler vom Feld bekommen, hilft die Antwort "Aber ... ich habe keinen Debugger" nicht weiter. Daher müssen Sie eine Reihe von Fähigkeiten zur Fehlerbehebung und zum Auffinden des Fehlers entwickeln, indem Sie die Code- und Protokolldateien verstehen.

0
yarony