it-swarm-eu.dev

Wie kann man Code am effektivsten debuggen?

Fehler, die sich in den Code einschleichen, können minimiert, aber nicht vollständig beseitigt werden, wie es geschrieben steht - Programmierer sind, obwohl viele nicht einverstanden , nur Menschen.

Was können wir tun, um einen Fehler in unserem Code zu beseitigen, wenn wir ihn entdecken? Wie sollten wir uns dem nähern, um unsere wertvolle Zeit optimal zu nutzen und weniger Zeit damit zu verbringen, sie zu finden, und mehr Zeit für die Codierung? Was sollten wir beim Debuggen vermeiden?

Beachten Sie hier, dass wir nicht über das Verhindern von Fehlern sprechen. Wir sprechen darüber, was zu tun ist, wenn Fehler auftreten. Ich weiß, dass dies ein weites Feld ist, das möglicherweise stark von Sprache, Plattform und Tools abhängt. Wenn ja, bleiben Sie bei umfassenden Antworten wie Denkweisen und allgemeinen Methoden.

33
gablin

Die Einstellung und Einstellung zum Debuggen ist vielleicht der wichtigste Teil, da sie bestimmt, wie effektiv Sie den Fehler beheben und was Sie daraus lernen - wenn überhaupt.

Klassiker der Softwareentwicklung wie The Pragmatic Programmer und Code Complete argumentieren grundsätzlich für denselben Ansatz: Jeder Fehler ist eine Chance zu lernen, fast immer über sich selbst (weil nur Anfänger zuerst den Compiler/Computer beschuldigen).

Behandle es also als ein Rätsel, das interessant zu knacken sein wird. Und dieses Rätsel zu lösen, sollte systematisch gelöst werden, indem wir unsere Annahmen (uns selbst oder anderen gegenüber) zum Ausdruck bringen und dann unsere Annahmen gegebenenfalls einzeln testen - unter Verwendung aller uns zur Verfügung stehenden Tools, insbesondere Debugger und automatisierter Test-Frameworks. Nachdem das Rätsel gelöst ist, können Sie es noch besser machen, indem Sie Ihren gesamten Code nach ähnlichen Fehlern durchsuchen, die Sie möglicherweise gemacht haben. und schreiben Sie einen automatisierten Test, um sicherzustellen, dass der Fehler nicht unwissentlich erneut auftritt.

Ein letzter Hinweis - ich nenne Fehler lieber "Fehler" und nicht "Bugs" - Dijkstra warf seinen Kollegen vor, den letzteren Begriff zu verwenden, weil er unehrlich ist, und unterstützte die Idee, dass schädliche und launische Bug-Feen Bugs in unsere Programme gepflanzt haben, während wir nicht da waren. Ich schaue, anstatt wegen unseres eigenen (schlampigen) Denkens da zu sein: http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html

Wir könnten zum Beispiel damit beginnen, unsere Sprache zu bereinigen, indem wir einen Fehler nicht länger als Fehler bezeichnen, sondern als Fehler. Es ist viel ehrlicher, weil es die Schuld genau dahin bringt, wo sie hingehört, nämlich. mit dem Programmierer, der den Fehler gemacht hat. Die animistische Metapher des Fehlers, der sich böswillig eingeschlichen hat, während der Programmierer nicht hinschaute, ist intellektuell unehrlich, da sie verschleiert, dass der Fehler die eigene Schöpfung des Programmierers ist. Das Schöne an dieser einfachen Änderung des Wortschatzes ist, dass sie eine so tiefgreifende Wirkung hat: Während früher ein Programm mit nur einem Fehler "fast korrekt" war, ist ein Programm mit einem Fehler danach einfach "falsch" (weil in Error).

38
limist
  1. Schreiben Sie Tests. Testen ist nicht nur großartig, um Fehler zu verhindern (meiner Erfahrung nach beseitigt TDD, wenn es richtig gemacht wird, fast alle trivialen, dummen Fehler), sondern hilft auch beim Debuggen. Durch das Testen wird Ihr Design eher modular, was das Isolieren und Replizieren des Problems erheblich erleichtert. Außerdem kontrollieren Sie die Umgebung, sodass es weniger Überraschungen gibt. Wenn Sie einen fehlgeschlagenen Testfall erhalten, können Sie außerdem ziemlich sicher sein, dass Sie den tatsächlichen Grund für das Verhalten, das Sie stört, gefunden haben.

  2. Erfahren Sie, wie Sie einen Debugger verwenden. print Anweisungen mögen auf einer bestimmten Ebene recht gut funktionieren, aber ein Debugger ist meistens sehr hilfreich (und sobald Sie wissen, wie es geht Verwenden Sie es, es ist viel komfortabler als print Anweisungen).

  3. Sprechen Sie über jemanden über Ihr Problem, auch wenn es nur ein Gummiente ist. Sich selbst zu zwingen, das Problem, an dem Sie arbeiten, in Worten auszudrücken, tut wirklich Wunder.

  4. Geben Sie sich ein Zeitlimit. Wenn Sie beispielsweise nach 45 Minuten das Gefühl haben, dass Sie nirgendwo hingehen, wechseln Sie einfach für einige Zeit zu anderen Aufgaben. Wenn Sie zu Ihrem Fehler zurückkehren, werden Sie hoffentlich andere mögliche Lösungen sehen können, die Sie vorher nicht in Betracht gezogen hätten.

16
Ryszard Szopa

Zu diesem Thema habe ich ein ausgezeichnetes Buch mit dem Titel Why Programs Fail gelesen, in dem verschiedene Strategien zum Auffinden von Fehlern beschrieben werden, die von der Anwendung der wissenschaftlichen Methode zum Isolieren und Beheben eines Fehlers bis zum Delta-Debuggen reichen. Der andere interessante Teil dieses Buches ist, dass es den Begriff "Bug" beseitigt. Zellers Ansatz ist:

(1) Ein Programmierer erstellt einen Fehler im Code. (2) Der Defekt verursacht eine Infektion. (3) Die Infektion breitet sich aus. (4) Die Infektion verursacht ein Versagen.

Wenn Sie Ihre Debugging-Fähigkeiten verbessern möchten, empfehle ich dieses Buch.

Nach meiner persönlichen Erfahrung habe ich viele Fehler in unserer Anwendung gefunden, aber das Management drängt uns einfach weiter, um neue Funktionen herauszubringen. Ich habe häufig gehört: "Wir haben diesen Fehler selbst gefunden und der Kunde hat ihn noch nicht bemerkt. Lassen Sie ihn also einfach, bis er es tut." Ich denke, dass es eine sehr schlechte Idee ist, reaktiv und nicht proaktiv Fehler zu beheben, da es an der Zeit ist, tatsächlich Probleme zu beheben. Sie haben andere Probleme, die behoben werden müssen, und das Management weiterer Funktionen möchte so schnell wie möglich aus der Tür, sodass Sie erwischt werden in einem Teufelskreis, der zu viel Stress und Burn-out und letztendlich zu einem defekten System führen kann.

Kommunikation ist auch ein weiterer Faktor, wenn Fehler gefunden werden. Das Versenden oder Dokumentieren einer E-Mail im Bug-Tracker ist in Ordnung und in Ordnung, aber meiner Erfahrung nach finden andere Entwickler einen ähnlichen Fehler und verwenden die von Ihnen verwendete Lösung zur Behebung des Codes nicht wieder (da sie alles vergessen haben) ) fügen sie ihre eigenen Versionen hinzu, sodass Sie 5 verschiedene Lösungen in Ihrem Code haben und dieser dadurch aufgeblähter und verwirrender aussieht. Wenn Sie also einen Fehler beheben, stellen Sie sicher, dass einige Leute den Fix überprüfen und Ihnen Feedback geben, falls sie etwas Ähnliches behoben und eine gute Strategie gefunden haben, um damit umzugehen.

limist erwähnte das Buch The Pragmatic Programmer , das interessantes Material zur Behebung von Fehlern enthält. Anhand des Beispiels, das ich im vorherigen Absatz gegeben habe, würde ich Folgendes betrachten: Software Entrophy , wobei die Analogie einer kaputten Witwe verwendet wird. Wenn zwei, viele zerbrochene Fenster angezeigt werden, kann es sein, dass Ihr Team apathisch wird, es jemals zu reparieren, es sei denn, Sie nehmen eine proaktive Haltung ein.

3
Desolate Planet

Ich mag die meisten anderen Antworten, aber hier sind einige Tipps, was zu tun ist, bevor Sie etwas davon tun. Sparen Sie Zeit.

  1. Stellen Sie fest, ob wirklich ein Fehler vorliegt. Ein Fehler ist IMMER ein Unterschied zwischen Systemverhalten und Anforderungen. Der Tester sollte in der Lage sein, das erwartete und tatsächliche Verhalten zu artikulieren. Wenn er nicht in der Lage ist, das erwartete Verhalten zu unterstützen, gibt es keine Anforderung und keinen Fehler - nur die Meinung von jemandem. Sende es zurück.

  2. Berücksichtigen Sie die Möglichkeit, dass das erwartete Verhalten falsch ist. Dies könnte auf eine Fehlinterpretation der Anforderung zurückzuführen sein. Dies kann auch auf einen Fehler in der Anforderung selbst zurückzuführen sein (ein Delta zwischen einer detaillierten Anforderung und einer Geschäftsanforderung). Sie können diese auch zurückschicken.

  3. Isolieren Sie das Problem. Nur die Erfahrung wird Ihnen den schnellsten Weg zeigen, dies zu tun - manche Menschen können es fast mit ihrem Bauch tun. Ein grundlegender Ansatz besteht darin, eine Sache zu variieren und dabei alle anderen Dinge konstant zu halten (tritt das Problem in anderen Umgebungen - mit anderen Browsern - in einer anderen Testregion - zu verschiedenen Tageszeiten auf?). Ein anderer Ansatz besteht darin, Stack-Dumps oder zu betrachten Fehlermeldungen - manchmal können Sie anhand der Formatierung erkennen, welche Komponente des Systems den ursprünglichen Fehler ausgelöst hat (z. B. wenn es auf Deutsch ist, können Sie dem Dritten, mit dem Sie in Berlin arbeiten, die Schuld geben).

  4. Wenn Sie es auf zwei Systeme eingegrenzt haben, die zusammenarbeiten, überprüfen Sie die Nachrichten zwischen den beiden Systemen über Verkehrsüberwachungs- oder Protokolldateien und stellen Sie fest, welches System sich gemäß den Spezifikationen verhält und welches nicht. Wenn das Szenario mehr als zwei Systeme enthält, können Sie paarweise Überprüfungen durchführen und sich im Anwendungsstapel "nach unten" arbeiten.

  5. Der Grund, warum das Isolieren des Problems so kritisch ist, besteht darin, dass das Problem möglicherweise nicht auf einen Codefehler zurückzuführen ist, über den Sie die Kontrolle haben (z. B. Systeme von Drittanbietern oder die Umgebung), und Sie möchten, dass diese Partei so schnell wie möglich die Kontrolle übernimmt . Dies dient sowohl dazu, Ihnen Arbeit zu ersparen als auch sie sofort auf den Punkt zu bringen, damit die Auflösung in einem möglichst kurzen Zeitrahmen erreicht werden kann. Sie möchten zehn Tage lang nicht an einem Problem arbeiten, nur um festzustellen, dass es sich wirklich um ein Problem mit dem Webdienst eines anderen handelt.

  6. Wenn Sie festgestellt haben, dass tatsächlich ein Fehler vorliegt und der von Ihnen kontrollierte Code tatsächlich vorhanden ist, können Sie das Problem weiter eingrenzen, indem Sie nach dem letzten "bekanntermaßen guten" Build suchen und die Quellcodeverwaltungsprotokolle auf Änderungen untersuchen, die das Problem möglicherweise verursacht haben. Dies kann viel Zeit sparen.

  7. Wenn Sie es nicht aus der Quellcodeverwaltung herausfinden können, ist es jetzt an der Zeit, Ihren Debugger anzuhängen und den Code durchzugehen, um es herauszufinden. Wahrscheinlich haben Sie inzwischen sowieso eine ziemlich gute Vorstellung von dem Problem.

Wenn Sie wissen, wo sich der Fehler befindet und sich eine Lösung vorstellen können, finden Sie hier eine gute Vorgehensweise, um ihn zu beheben:

  1. Schreiben Sie einen Komponententest, der das Problem reproduziert und fehlschlägt.

  2. Lassen Sie den Komponententest bestehen, ohne ihn zu ändern (indem Sie den Anwendungscode ändern).

  3. Bewahren Sie den Komponententest in Ihrer Testsuite auf, um eine Regression zu verhindern/zu erkennen.

3
John Wu

Fehler, Irrtum, Problem, Defekt - wie auch immer Sie es nennen möchten, es macht keinen großen Unterschied. Ich bleibe beim Problem, da ich das gewohnt bin.

  1. Finden Sie heraus, wie das Problem wahrgenommen wird: Übersetzen Sie von "Bob ist noch nicht im System" eines Kunden in "Wenn ich versuche, einen Benutzerdatensatz für Bob zu erstellen", schlägt dies mit einer doppelten Schlüsselausnahme fehl, obwohl Bob dies noch nicht getan hat da drin'
  2. Finden Sie heraus, ob es wirklich ein Problem oder nur ein Missverständnis ist (tatsächlich ist Bob nicht da, es gibt niemanden namens Bob, und das Einfügen sollte funktionieren).
  3. Versuchen Sie, minimale zuverlässige Schritte zu erhalten, die Sie ausführen können, um das Problem zu reproduzieren. Wenn beispielsweise bei einem System mit einem Benutzerdatensatz "Bruce" ein Benutzerdatensatz "Bob" eingefügt wird, tritt eine Ausnahme auf. "
  4. Dies ist Ihr Test - wenn möglich, legen Sie ihn in ein automatisiertes Testkabel, das Sie immer wieder ausführen können. Dies ist beim Debuggen von unschätzbarem Wert. Sie können es auch zu einem Teil Ihrer Testsuite machen, um sicherzustellen, dass dieses spezielle Problem später nicht erneut auftritt.
  5. Holen Sie Ihren Debugger heraus und setzen Sie Haltepunkte. Ermitteln Sie den Codepfad, wenn Sie Ihren Test ausführen, und ermitteln Sie, was falsch ist. Während Sie dies tun, können Sie Ihren Test auch verfeinern, indem Sie ihn so eng wie möglich gestalten - idealerweise einen Komponententest.
  6. Beheben Sie das Problem - überprüfen Sie Ihre Testdurchläufe.
  7. Stellen Sie sicher, dass das ursprüngliche Problem, wie vom Kunden beschrieben, ebenfalls behoben ist (sehr wichtig - möglicherweise haben Sie nur eine Teilmenge des Problems behoben). Stellen Sie sicher, dass Sie in anderen Aspekten des Programms keine Regressionen eingeführt haben.

Wenn Sie mit dem Code sehr vertraut sind oder wenn das Problem oder die Lösung offensichtlich ist, können Sie einige dieser Schritte überspringen.

Wie sollten wir uns dem nähern, um unsere wertvolle Zeit optimal zu nutzen und weniger Zeit damit zu verbringen, sie zu finden, und mehr Zeit für die Codierung?

Ich habe Probleme damit, da dies impliziert, dass das Schreiben von neuem Code wertvoller ist als ein qualitativ hochwertiges Arbeitsprogramm. Es ist nichts Falsches daran, Probleme so effektiv wie möglich zu beheben, aber ein Programm wird nicht unbedingt besser, wenn nur mehr Code hinzugefügt wird.

3
ptyx

Ich denke, die Reproduktion eines Fehlers ist ebenfalls wichtig. Alle Fälle, die den Fehler reproduzieren, können aufgelistet werden. Anschließend können Sie sicherstellen, dass Ihre Fehlerbehebung alle diese Fälle abdeckt.

3
aslisabanci

Was können wir tun, wenn wir einen Fehler in unserem Code feststellen, um ihn auszusortieren? Wie sollten wir uns dem nähern, um unsere wertvolle Zeit optimal zu nutzen und weniger Zeit damit zu verbringen, sie zu finden, und mehr Zeit für die Codierung? Was sollten wir beim Debuggen vermeiden?

Angenommen, Sie befinden sich in einer Produktionsumgebung, müssen Sie Folgendes tun:

  1. Beschreiben Sie den "Fehler" richtig und identifizieren Sie die Ereignisse, die ihn verursachen.

  2. Stellen Sie fest, ob der "Fehler" ein Codefehler oder ein Spezifikationsfehler ist. Beispielsweise kann die Eingabe eines 1-Buchstaben-Namens für einige Systeme als Fehler angesehen werden, für andere Systeme jedoch als akzeptables Verhalten. Manchmal meldete ein Benutzer einen Fehler, den er für ein Problem hält, aber die Erwartung des Benutzers an das Verhalten des Systems war nicht Teil der Anforderungen.

  3. Wenn Sie nachgewiesen haben, dass ein Fehler vorliegt und der Fehler auf den Code zurückzuführen ist, können Sie bestimmen, welche Codeteile repariert werden müssen, um den Fehler zu vermeiden. Untersuchen Sie auch die Auswirkungen des Verhaltens auf aktuelle Daten und zukünftige Systemoperationen (Auswirkungsanalyse auf Code und Daten).

  4. Zu diesem Zeitpunkt hätten Sie wahrscheinlich eine Schätzung, wie viel Ressourcen verbraucht werden, um den Fehler zu beheben. Sie können das Problem entweder sofort beheben oder eine Korrektur in einer kommenden Version der Software planen. Dies hängt auch davon ab, ob der Endbenutzer bereit ist, für das Update zu zahlen. Sie sollten auch verschiedene verfügbare Optionen bewerten, um den Fehler zu beheben. Es kann mehr als einen Weg geben. Sie müssen den Ansatz auswählen, der der Situation am besten entspricht.

  5. Analysieren Sie die Gründe, aus denen dieser Fehler aufgetreten ist (Anforderungen, Codierung, Tests usw.). Erzwingen Sie Prozesse, die verhindern, dass der Zustand erneut auftritt.

  6. Dokumentieren Sie die Episode angemessen.

  7. Geben Sie das Update (oder die neue Version) frei.

1
NoChance

So mache ich das:

  1. verwenden Sie jedes Mal dieselbe Methode, um das Problem zu finden. Dies verbessert Ihre Reaktionszeit auf die Fehler.
  2. Der beste Weg ist wahrscheinlich, den Code zu lesen. Dies liegt daran, dass alle Informationen im Code verfügbar sind. Sie brauchen nur effiziente Wege, um die richtige Position zu finden und alle Details zu verstehen.
  3. das Debuggen ist sehr langsam und nur erforderlich, wenn Ihre Programmierer noch nicht verstehen, wie der Computer asm-Anweisungen ausführt/Call-Stacks und grundlegende Dinge nicht verstehen kann
  4. Versuchen Sie, Proof-Techniken wie die Verwendung von Funktionsprototypen zu entwickeln, um über das Verhalten des Programms nachzudenken. Dies hilft, die richtige Position schneller zu finden
1
tp1