Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert wird, bevor er diagnostiziert und behoben wird?


70

Ich arbeite für eine Softwareproduktfirma. Wir haben große Unternehmenskunden, die unser Produkt implementieren und die wir unterstützen. Wenn zum Beispiel ein Fehler vorliegt, stellen wir Patches usw. zur Verfügung. Mit anderen Worten, es handelt sich um eine recht typische Konfiguration.

Kürzlich wurde mir ein Ticket ausgestellt und zugewiesen, das sich auf eine von einem Kunden in einer Protokolldatei festgestellte Ausnahme bezieht, die mit dem gleichzeitigen Datenbankzugriff in einer Clusterimplementierung unseres Produkts zu tun hat. Die spezifische Konfiguration dieses Kunden kann daher für das Auftreten dieses Fehlers von entscheidender Bedeutung sein. Alles, was wir vom Kunden bekamen, war die Protokolldatei.

Der Ansatz, den ich meinem Team vorgeschlagen hatte, bestand darin, zu versuchen, den Fehler in einer Konfiguration zu reproduzieren, die der des Kunden ähnelt, und ein vergleichbares Protokoll zu erhalten. Sie stimmen jedoch nicht mit meinem Ansatz überein, dass ich den Fehler nicht reproduzieren muss, da er zu zeitaufwändig ist und die Simulation eines Serverclusters auf VMs erforderlich macht. Mein Team schlägt vor, einfach "dem Code zu folgen", um festzustellen, wo sich der Thread- und / oder Transaktions-unsichere Code befindet, und die Änderung einer einfachen lokalen Entwicklung vorzunehmen, bei der es sich nicht um eine Cluster-Implementierung handelt, wie in der Umgebung, in der das Ereignis auftritt des Fehlers entsteht.

Für mich scheint es schwierig zu sein, einen abstrakten Entwurf (Programmcode) anstelle einer sichtbaren Manifestation (Laufzeitreproduktion) zu verwenden. Deshalb wollte ich eine allgemeine Frage stellen:

Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert und behoben wird, bevor er diagnostiziert und behoben wird?

Oder:

Wenn ich ein erfahrener Entwickler bin, sollte ich in der Lage sein, Multithread-Code zu lesen und ein mentales Bild davon zu erstellen, was er in allen Anwendungsszenarien tut, anstatt die Anwendung auszuführen, verschiedene Anwendungsszenarien zu testen und die Schritte durchzuarbeiten Code Zeile für Zeile? Oder bin ich ein schlechter Entwickler, weil ich so ein Arbeitsumfeld fordere?

Debuggen für Weichlinge?

Meiner Meinung nach sollte jeder Fix, der als Antwort auf ein Incident-Ticket eingereicht wird, in einer Umgebung getestet werden, die simuliert wurde, um der ursprünglichen Umgebung so nahe wie möglich zu sein. Woher können Sie sonst wissen, dass das Problem wirklich behoben wird? Es ist, als würde man ein neues Fahrzeugmodell veröffentlichen, ohne es mit einem Dummy einem Crashtest zu unterziehen, um zu demonstrieren, dass die Airbags tatsächlich funktionieren.

Zu guter Letzt, wenn Sie mir zustimmen:

Wie soll ich mit meinem Team sprechen, um sie davon zu überzeugen, dass mein Ansatz vernünftig, konservativ und kugelsicherer ist?


7
Manchmal macht es keinen Sinn, auf die Reproduktion zu bestehen, wenn Sie ein Protokoll mit Stack-Trace haben. Einige Parallelitätsfehler in Java sind einfach so. Am einfachsten ist es, wenn Sie ein Protokoll mit NPE und Stack-Trace erhalten, das auf eine Zeile verweist, die "anscheinend" ein Objekt verwendet, mit dem sie erstellt wurden new. Und es ist nicht garantiert, dass diese Fehler zuverlässig reproduzierbar sind, gemäß der Java Memory Model-Spezifikation
gnat

5
Möchten Sie die "richtige" Antwort - Sie müssen jeden Fehler reproduzieren, damit Sie wissen, ob er behoben ist, oder die Antwort "Der Kunde zahlt uns weiterhin $$" - manchmal haben Sie nicht die Zeit und die Ressourcen, dies zu tun, und Ihr Chef erwartet von Ihnen, dass Sie Ihr Fachwissen einsetzen, um es trotzdem zu beheben?
KutuluMike


20
Überrascht, dass die Community hier mit Ihnen übereinstimmt. Ehrlich gesagt, stimme ich Ihren Teamkollegen voll und ganz zu. Manchmal, besonders wenn es um Fehler unter Rennbedingungen geht, ist es viel sinnvoller und effizienter, einfach dem Code zu folgen, als eine Menge Zeit damit zu verbringen, eine Testumgebung zu erstellen , die das Problem möglicherweise nicht einmal aufdeckt . Wenn Sie durch das Verfolgen des Codes nichts finden können, prüfen Sie, ob es sinnvoll ist, die Erstellung einer Testumgebung in Anspruch zu nehmen, aber es ist eine schlechte Zeitaufteilung, um mit der Erstellung der Testumgebung zu beginnen .
Ben Lee

5
Sie können nicht nachweisen, dass Sie das Problem behoben haben, ohne es replizieren zu können. Gelegentlich mag es sinnvoll sein, eine Vermutung über Ressourcenbeschränkungen anzustellen, aber ich möchte, dass dies die Ausnahme und nicht die Regel ist. Wenn es jedoch wirklich so schwierig ist, Probleme zu reproduzieren, liegt möglicherweise ein anderes Problem vor, beispielsweise das zugrunde liegende Design oder die zugrunde liegende Architektur.
Dietbuddha

Antworten:


72

Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert und behoben wird, bevor er diagnostiziert und behoben wird?

Du solltest dein Bestes geben. Ich weiß , dass manchmal gibt es Bedingungen und Umgebungen , die so komplex sind , können sie nicht reproduziert werden genau , aber Sie sollten auf jeden Fall versuchen , wenn Sie können.

Wenn Sie den Fehler nie reproduziert und selbst gesehen haben, wie können Sie dann 100% sicher sein, dass Sie ihn wirklich behoben haben? Möglicherweise führt Ihre vorgeschlagene Fehlerbehebung einen anderen subtilen Fehler ein, der erst dann auftritt, wenn Sie tatsächlich versuchen , den ursprünglichen Fehler zu reproduzieren.

Wenn ich ein leitender Entwickler bin, sollte ich in der Lage sein, (Multithread-) Code zu lesen und mir ein Bild davon zu machen, was er in allen Anwendungsszenarien tut, anstatt die Anwendung auszuführen, verschiedene Anwendungsszenarien zu testen und durchzuarbeiten der Code Zeile für Zeile? Oder bin ich ein schlechter Entwickler, weil ich so ein Arbeitsumfeld fordere? Debuggen für Weichlinge?

Ich würde niemandem vertrauen, der den Code "im Kopf" laufen lässt, wenn dies der einzige Ansatz ist. Es ist ein guter Anfang . Reproduzieren Sie den Fehler und beheben Sie ihn. Zeigen Sie dann , dass die Lösung verhindert, dass der Fehler erneut auftritt. Hier sollte er enden .

Wie soll ich mit meinem Team sprechen, um sie davon zu überzeugen, dass mein Ansatz vernünftig, konservativ und kugelsicherer ist?

Denn wenn sie den Fehler nie reproduziert haben, können sie nicht sicher sein, dass er behoben ist. Und wenn der Kunde zurückkommt und sich beschwert, dass der Fehler immer noch da ist, ist das keine gute Sache. Immerhin zahlen sie Ihnen viel Geld (nehme ich an), um dieses Problem zu lösen.

Wenn Sie nicht das Problem richtig zu beheben, haben Sie gebrochen Glauben mit dem Kunden (bis zu einem gewissen Grad) , und wenn es Wettbewerber in Ihrem Markt sind, können sie nicht Ihre Kunden bleiben.


3
"Den Fehler reproduzieren und beheben und dann demonstrieren, dass die Lösung das Wiederauftreten des Fehlers verhindert - hier sollte er enden." - Mein Punkt genau
amphibient

2
"Denn wenn sie den Fehler nie reproduziert haben, können sie nicht sicher sein, dass er behoben ist." Amen ...
Marjan Venema

11
Ich möchte auch zu dieser Antwort hinzufügen, dass Ihr Unternehmen herausfinden sollte, ob dies überhaupt eine unterstützte Konfiguration ist, da Sie diese Konfiguration nicht haben. Wenn Ihr Unternehmen solche Konfigurationen offiziell unterstützen wird, sollten Sie eine Umgebung haben, die ähnlich konfiguriert ist, nur um Ihre QS-Arbeit zu erledigen. Das wird sicherlich die Kosten erhöhen, und deshalb sollte das Unternehmen entscheiden, welche Konfigurationen seines Produkts unterstützt werden sollen.
Andy

Hier sollte es ein Kosten / Nutzen-Argument geben. Wenn die Reproduktion Wochen dauert, ist der Wert der Reproduktion wahrscheinlich niedrig, da andere Probleme nicht angegangen werden. Wenn die Wiedergabe einige Sekunden dauert, ist der Wiedergabewert aufgrund der Sicherheit der Fehlerbehebung wahrscheinlich hoch. Die Entscheidung sollte versuchen, dies auszugleichen, eine pauschale "sollte" oder "sollte nicht" -Aussage ist nutzlos.
Orip

1
@orip: Kosten / Nutzen-Analyse muss auch den Kunden berücksichtigen: Gibt es die Kosten für das Ignorieren des Kunden mit dem möglichen Risiko des Verlusts des Kontos (und möglicherweise des Verlusts anderer Kunden aufgrund dessen, was sie von diesem ursprünglichen Kunden hören, oder wenn sie dies tun) Tritt der Fehler auch auf, muss er jedoch noch offiziell gemeldet werden?) Wie hoch sind die Kosten für die Zeit, die Entwickler für das Reproduzieren und Beheben des Fehlers aufwenden?
FrustratedWithFormsDesigner

35

Wie wollen sie überprüfen, ob der betreffende Fehler behoben wurde? Möchten sie nicht getesteten Code an den Benutzer senden und ihn herausfinden lassen? Jeder Testaufbau, von dem nie gezeigt wurde, dass er den Fehler reproduziert, kann nicht als Beleg für die Abwesenheit des Fehlers herangezogen werden. Sie müssen sicherlich nicht die gesamte Client-Umgebung reproduzieren, aber Sie benötigen genug, um den Fehler zu reproduzieren.

Ich halte es nicht für unvernünftig, jeden Fehler zu reproduzieren, bevor er behoben wird. Wenn Sie jedoch versuchen, es zu reproduzieren, und Sie können es nicht, dann ist es eher eine geschäftliche Entscheidung, ob Blind Patches eine gute Idee sind oder nicht.


2
Ich stimme jedoch zu, dass ein Fehler, der durch Überprüfung gefunden wird, wichtige Informationen liefern kann, die für die Reproduktion erforderlich sind. Sie können es dann reproduzieren und nachweisen, dass die Fehlerbehebung korrekt ist ...
mattnz

3
Wenn Sie in der Lage sind, eine Multithread-Race-Bedingung durch Codeinspektion zu ermitteln, sollten Sie in der Lage sein, sie konsistent zu reproduzieren, indem Sie den Code mit zusätzlichen Sperranweisungen modifizieren, die das Starten / Stoppen der Threads in einer Sequenz erzwingen, die ihn auslöst. ex Thread1 - Starten und Anhalten, Thread2 - Starten und Anhalten, 1 - Verwenden von gemeinsam genutztem Objekt und Anhalten, 2 - Ändern von gemeinsam genutztem Objekt und Anhalten, 1 - Verwenden von gemeinsam genutztem Objekt und Barf. Das größte Problem bei diesem Ansatz ist, dass er zwar in einem Debugger demonstriert werden kann, aber nicht für das Hinzufügen zu einer automatisierten Testsuite geeignet ist. BTDT-GTTS.
Dan Neely

2
@DanNeely: Wenn ein Thread einen Wert in ein Array schreibt und dann eine Referenz in einem Feld speichert und ein anderer Thread dieses Feld liest und auf das entsprechende Array-Element zugreift, wie würde man Fehler reproduzieren, die auftreten könnten, wenn die JIT die Schreibreferenz verschiebt Operation vor dem Schreibelement?
Supercat

27

Idealerweise möchten Sie jeden Fehler reproduzieren können, damit Sie zumindest testen können, ob er behoben wurde.

Aber ... Das ist vielleicht nicht immer machbar oder sogar physikalisch möglich. Insbesondere bei Unternehmenssoftware, bei der jede Installation einzigartig ist. Es gibt auch die Kosten-Nutzen-Bewertung. Ein paar Stunden Code durchzusehen und ein paar fundierte Vermutungen über ein nicht kritisches Problem anzustellen, kann weitaus weniger kosten, als wenn ein Team des technischen Supports wochenlang versucht, die Umgebung eines Kunden genau in der Hoffnung einzurichten und zu duplizieren, die Umgebung zu duplizieren Problem. Früher, als ich in der 'Enterprise'-Welt arbeitete, flogen wir oft nur Codierer heraus und ließen sie Fehler vor Ort beheben, da es keine Möglichkeit gab, das Setup des Kunden zu duplizieren.

Also duplizieren Sie, wenn Sie können, aber wenn Sie nicht können, machen Sie sich Ihr Wissen über das System zunutze und versuchen Sie, den Täter im Code zu identifizieren.


11

Ich denke nicht, dass Sie eine Reproduktion des Fehlers zu einer Bedingung machen sollten, um den Fehler zu untersuchen. Wie Sie bereits erwähnt haben, gibt es verschiedene Möglichkeiten, um das Problem zu beheben - und Sie sollten alle verwenden. Sie sollten sich glücklich schätzen, dass sie Ihnen eine Protokolldatei geben konnten! Wenn Sie oder jemand in Ihrem Unternehmen in der Lage ist, den Fehler zu reproduzieren, großartig! Wenn nicht, sollten Sie dennoch versuchen, die Protokolle zu analysieren und die Umstände zu ermitteln, unter denen der Fehler aufgetreten ist. Wie Ihre Kollegen vorgeschlagen haben, ist es möglicherweise möglich, den Code zu lesen, herauszufinden, unter welchen Bedingungen der Fehler auftreten könnte, und dann zu versuchen, das Szenario selbst neu zu erstellen.

Veröffentlichen Sie jedoch nicht den aktuellen Fix, der noch nicht getestet wurde. Jede Änderung, die Sie vornehmen, sollte die Standardroutine für Entwickler-, Qualitätssicherungs- und Integrationstests durchlaufen. Es kann sich als schwierig erweisen, es zu testen - Sie haben Multithread-Code erwähnt, der notorisch schwer zu debuggen ist. Hier stimme ich Ihrem Ansatz zur Erstellung einer Testkonfiguration oder -umgebung zu. Wenn Sie ein Problem im Code gefunden haben, sollten Sie es viel einfacher finden, die Umgebung zu erstellen, das Problem zu reproduzieren und das Update zu testen.

Für mich handelt es sich weniger um ein Debugging-Problem als vielmehr um ein Kundendienstproblem. Sie haben einen Fehlerbericht von einem Kunden erhalten. Sie sind verpflichtet, die erforderliche Sorgfalt zu walten, um das Problem zu finden und zu beheben.


5
„Aber lassen Sie nicht die tatsächliche fix ungetestet.“ Wie? Wenn er die Bedingungen, die den Fehler verursacht haben, nicht reproduzieren kann, wie wird er sie reproduzieren, um den Fix zu testen? Auch würde ich nicht annehmen, dass OP nicht seine besten Anstrengungen unternahm.
Tulains Córdova

"Wenn Sie ein Problem im Code gefunden haben, sollten Sie es viel einfacher finden, die Umgebung zu erstellen, das Problem zu reproduzieren und das Update zu testen." Ich habe die Frage des OP gelesen: "Soll ich für alle Fehlerberichte einen Repro-Fall anfordern, bevor ich versuche, das Problem zu diagnostizieren?" Nein, das solltest du nicht.
Michael K

Ich würde erwarten, dass die meisten Tests Regressionstests für vorhandene Features sind.
Michael Durrant

4
@MichaelK: Deine Antwort scheint mit sich selbst zu kollidieren. Wenn Sie nicht wissen, in welchen Schritten der Fehler reproduziert werden soll, wie werden Sie dann jemals erfahren, wie Ihre Testfälle aussehen sollten? Möglicherweise müssen Sie die Fehler nicht immer selbst reproduzieren, aber die meisten dieser Fälle treten auf, wenn die zu reproduzierenden Schritte bereits bekannt sind. Wenn Sie nur eine Protokolldatei ohne bekannte Schritte haben, haben Sie keine Testfälle, mit denen Sie die Qualitätssicherung durchführen können.
Ellesedil

8
Ich denke, was er sagt, ist, dass Sie das Problem nicht unbedingt reproduzieren müssen, um eine Lösung dafür zu finden. Angenommen, Sie suchen danach und finden einen Fix. Dann kennen Sie die Bedingungen, die auf dem Testserver für die Reproduktion eingerichtet werden müssen. An diesem Punkt wüssten Sie sogar, wie Sie den vorherigen Code einrichten - richten Sie ihn ein, überprüfen Sie, ob er reproduzierbar ist, stellen Sie den Fix bereit und überprüfen Sie, ob er behoben ist.
GalacticCowboy

9

Meiner Meinung nach ... müssen Sie als Entscheidungsträger Ihre Position rechtfertigen können. Wenn das Ziel der 3rd Line Support-Abteilung darin besteht, Fehler in kürzester Zeit mit dem akzeptablen Aufwand des Kunden zu beheben, muss jeder Ansatz diesem Ziel entsprechen. Darüber hinaus sollte es kein Problem geben, das Team zu überzeugen, wenn nachgewiesen werden kann, dass der Ansatz die schnellsten erwarteten Ergebnisse liefert.

Nachdem ich im Support gearbeitet habe, habe ich vernünftigerweise erwartet, dass der Client einige "Skripte" von Aktionen geben kann, die er ausgeführt hat, um den Fehler konsistent zu reproduzieren, und, wenn nicht konsistent, Kandidatenbeispiele, die den Fehler verursacht haben.

Wenn ich neu im System wäre und keinen Hintergrund mit dem Code hätte, würden meine ersten Schritte darin bestehen, die möglichen Fehlerquellen zu identifizieren. Möglicherweise reicht die Protokollierung nicht aus, um einen Kandidatencode zu identifizieren. Je nach Client bin ich möglicherweise geneigt, ihnen eine Debug-Version zu geben, damit sie möglicherweise Protokolldateien zurückgeben können, die weitere Hinweise auf die Position des fehlerhaften Codes geben.

Wenn ich in der Lage bin, den Codeblock schnell zu identifizieren, kann eine visuelle Abbildung des Flusses ausreichen, um den Code zu erkennen. Wenn nicht, kann eine auf Unit-Tests basierende Simulation ausreichend sein. Es kann sein, dass das Einrichten einer Clientreplikationsumgebung weniger Zeit in Anspruch nimmt, insbesondere wenn das Problem in hohem Maße reproduzierbar ist.

Ich denke, Sie werden vielleicht feststellen, dass Ihr Ansatz eine Kombination der vorgeschlagenen Lösungen sein sollte und dass es der Schlüssel ist, um die Arbeit effizient zu erledigen, wenn Sie wissen, wann Sie eine beenden und mit der nächsten fortfahren müssen.

Ich bin mir ziemlich sicher, dass das Team die Vorstellung unterstützen wird, dass, wenn es eine Chance gibt, dass ihre Lösung den Fehler schneller findet, und ihnen dann einen geeigneten Zeitrahmen gibt, um zu beweisen, dass sich dies nicht zu stark auf die Zeit auswirkt, die zur Behebung des Fehlers erforderlich ist, je nachdem, welcher Fall Route, die Sie nehmen.


8

Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert und behoben wird, bevor er diagnostiziert und behoben wird?

Ich sage ja, mit einigen Einschränkungen.

  • Ich denke, es ist in Ordnung, den Code durchzulesen und Orte zu finden, die problematisch aussehen. Erstellen Sie einen Patch und senden Sie diesen an den Client, um zu prüfen, ob das Problem dadurch behoben wird. Wenn dieser Ansatz weiterhin fehlschlägt, müssen Sie möglicherweise andere Optionen untersuchen. Denken Sie daran, dass Sie möglicherweise einen Fehler beheben, aber möglicherweise nicht den gemeldeten Fehler.
  • Wenn Sie es nicht innerhalb des Rahmens reproduzieren können und keine roten Fahnen im Code finden, ist möglicherweise eine engere Abstimmung mit dem Kunden erforderlich. Ich bin schon früher zu Kunden geflogen, um vor Ort Fehler zu beheben. Es ist nicht die beste Entwicklungsumgebung, aber manchmal, wenn das Problem in der Umgebung liegt, ist es am einfachsten, die genaue Ursache zu finden, wenn Sie sie konsistent reproduzieren können.

Ich war in diesem Szenario auf der Kundenseite. Ich arbeitete in einem US-Regierungsbüro, das einen unglaublich großen Oracle-Datenbankcluster verwendete (mehrere Terabyte Daten und die Verarbeitung von Millionen Datensätzen pro Tag).

Wir stießen auf ein seltsames Problem, das sich für uns sehr leicht reproduzieren ließ. Wir haben Oracle den Fehler gemeldet und sind wochenlang mit ihnen hin und her gegangen und haben ihnen Protokolle gesendet. Sie sagten, sie könnten das Problem nicht reproduzieren, schickten uns aber ein paar Patches, mit denen sie das Problem beheben könnten. Keiner von ihnen tat es.

Sie haben schließlich ein paar Entwickler zu uns geflogen, um das Problem vor Ort zu beheben. In diesem Moment wurde die Ursache des Fehlers gefunden und ein späterer Patch hat das Problem korrekt behoben.


6

Wenn Sie dem Problem nicht positiv gegenüberstehen, können Sie der Lösung auch nicht positiv gegenüberstehen. Wenn Sie wissen, wie Sie das Problem in mindestens einer Testfallsituation zuverlässig reproduzieren können, können Sie nachweisen, dass Sie wissen, wie der Fehler verursacht wird, und können daher auch auf der anderen Seite nachweisen, dass das Problem aufgrund des nachfolgenden Mangels behoben wurde Fehler im gleichen Testfall nach dem Anwenden des Updates.

Das heißt, Race-Bedingungen, Nebenläufigkeitsprobleme und andere "nicht deterministische" Fehler sind für einen Entwickler am schwierigsten auf diese Weise zu lokalisieren, da sie selten auf einem System mit höherer Auslastung und mehr Komplexität auftreten als die Kopien eines Entwicklers das Programm, und sie verschwinden, wenn die Task zu einem späteren Zeitpunkt auf demselben System erneut ausgeführt wird.

Meistens hat das, was ursprünglich wie ein zufälliger Fehler aussieht, eine deterministische Ursache, die dazu führt, dass der Fehler deterministisch reproduzierbar ist, sobald Sie wissen, wie. Diejenigen, die sich dem widersetzen, die wahren Heisenbugs (scheinbar zufällige Bugs, die verschwinden, wenn Sie versuchen, sie in einer sterilen, überwachten Umgebung zu testen), sind zu 99,9% zeitbezogen, und sobald Sie das verstanden haben, wird Ihr Weg nach vorne klarer. Suchen Sie nach Dingen, die fehlschlagen könnten, wenn während der Ausführung des Codes ein anderes Wort auf den Kopf kommt. Wenn Sie eine solche Sicherheitsanfälligkeit finden, versuchen Sie, sie in einem Test auszunutzen, um festzustellen, ob sie das Verhalten aufweist, das Sie reproduzieren möchten.

In diesen Situationen ist in der Regel ein erheblicher Umfang eingehender Codeüberprüfungen erforderlich. Sie müssen sich den Code ansehen, alle vorgefassten Vorstellungen davon, wie sich der Code verhalten soll , aufgeben und sich Szenarien vorstellen, in denen der Code in der von Ihrem Client beobachteten Weise fehlschlagen könnte . Versuchen Sie für jedes Szenario, einen Test zu entwickeln, der in Ihrer aktuellen automatisierten Testumgebung effizient ausgeführt werden kann (dh, ohne dass ein neuer VM-Stack für diesen einen Test erforderlich ist), der beweist oder widerlegt, dass sich der Code wie erwartet verhält ( Dies würde, je nachdem, was Sie erwartet haben, beweisen oder widerlegen, dass dieser Code eine mögliche Ursache für die Probleme der Clients ist. Dies ist die wissenschaftliche Methode für Softwareentwickler. beobachten, hypothetisieren, testen, reflektieren, wiederholen.


4

Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert und behoben wird, bevor er diagnostiziert und behoben wird?

Nein, das ist es definitiv nicht. Das wäre eine blöde Politik.

Das Problem, das ich bei Ihrer Frage und Ihrem Vorschlag sehe, ist, dass sie nicht unterscheiden können zwischen

  • Fehlerberichte
  • Ausfälle ( Fehler )
  • Bugs (manchmal auch Fehler genannt )

Ein Fehlerbericht ist eine Mitteilung über einen Fehler. Es sagt dir, dass jemand denkt, dass etwas nicht stimmt. Es kann oder kann nicht spezifisch sein, was falsch sein soll.

Ein Fehlerbericht ist ein Hinweis auf einen Fehler.

Ein Misserfolg ist ein Vorfall, bei dem etwas schief geht. Eine bestimmte Fehlfunktion, aber nicht unbedingt mit Hinweisen darauf, was sie verursacht haben könnte.

Ein Fehler kann durch einen Fehler verursacht werden.

Ein Fehler ist eine Ursache für Fehler. Etwas, das (im Prinzip) geändert werden kann, um zu verhindern, dass die von ihm verursachten Fehler in der Zukunft auftreten.

Wenn ein Fehler gemeldet wird, ist die Ursache manchmal sofort klar. In einem solchen Fall wäre es unsinnig, den Fehler zu reproduzieren. In anderen Fällen ist die Ursache überhaupt nicht klar: Der Fehlerbericht beschreibt keinen bestimmten Fehler, aber der Fehler gibt keinen Hinweis darauf, was die Ursache sein könnte. In solchen Fällen halte ich Ihren Rat für berechtigt - aber nicht immer: Man besteht nicht darauf, eine zweite 370-Millionen-Dollar-Weltraumrakete zum Absturz zu bringen, bevor man sich bereit erklärt, zu untersuchen, was den ersten zum Absturz gebracht hat (ein bestimmter Fehler in der Steuerungssoftware).

Und dazwischen gibt es auch alle möglichen Fälle; Wenn beispielsweise ein Fehlerbericht nicht beweist, sondern nur andeutet, dass ein potenzielles Problem, dessen Sie sich bereits bewusst waren, eine Rolle spielen könnte, ist dies möglicherweise ein Anreiz genug, es sich genauer anzusehen.

Das Beharren auf Reproduzierbarkeit ist für die härteren Fälle zwar ratsam, es ist jedoch nicht ratsam, es als strenge Richtlinie durchzusetzen.


4
Wenn es nicht sinnvoll ist, den Fehler zu reproduzieren, woher wissen Sie, dass Sie den Fehler behoben haben? Unabhängig davon, wie komplex die Art und Weise ist, Fehler zu reproduzieren.
BЈовић

Sie wissen, dass Sie den Fehler behoben haben, wenn die Reproduktion so einfach ist, dass Sie es nicht brauchen.
Reinierpost

Das Ziel ist nicht, Fehler zu beheben, sondern ein gutes Produkt zu haben. Sie nehmen eine Codeänderung vor, die den Code verbessert, und Ihrer Meinung nach und die Meinung des Überprüfers können den Fehler beheben. Dann wird das Produkt erneut getestet. Möglicherweise von unfreiwilligen Testern oder Endbenutzern.
gnasher729

Ich bin damit einverstanden, dass eine erneute Prüfung immer dann durchgeführt werden muss, wenn dies möglich ist, aber das ist nicht der springende Punkt. Hier stellt sich die Frage, ob es sinnvoll ist, immer darauf zu bestehen, dass das Problem überhaupt reproduzierbar ist.
Reinierpost

3

Wie bei allem anderen in der Softwareentwicklung ist die richtige Antwort ein Kompromiss.

Theoretisch sollten Sie niemals versuchen, einen Fehler zu beheben, wenn Sie nicht nachweisen können, dass er existiert. Dies kann dazu führen, dass Sie unnötige Änderungen an Ihrem Code vornehmen, die letztendlich nichts lösen. Und es zu beweisen bedeutet, es zuerst zu reproduzieren, dann einen Fix zu erstellen und anzuwenden und dann zu demonstrieren, dass es nicht mehr passiert. Ihr Bauch ist es, Sie in die richtige Richtung zu lenken. Wenn Sie sicher sein möchten, dass Sie das Problem Ihres Kunden gelöst haben, müssen Sie zunächst wissen, was es verursacht hat.

In der Praxis ist das nicht immer möglich. Möglicherweise tritt der Fehler nur in großen Clustern auf, in denen Dutzende Benutzer gleichzeitig auf Ihren Code zugreifen. Möglicherweise gibt es eine bestimmte Kombination von Datenoperationen für bestimmte Datensätze, die den Fehler auslösen, und Sie haben keine Ahnung, was das ist. Vielleicht hat Ihr Kunde das Programm 100 Stunden lang interaktiv ohne Unterbrechung ausgeführt, bevor der Fehler aufgetreten ist.

In all diesen Fällen besteht die große Wahrscheinlichkeit, dass Ihre Abteilung nicht die Zeit oder das Geld hat, um den Fehler zu reproduzieren, bevor Sie mit der Arbeit beginnen. In vielen Fällen ist es für Sie als Entwickler viel offensichtlicher, dass der Code einen Fehler enthält, der Sie auf die richtige Situation hinweist . Sobald Sie das Problem diagnostiziert haben, können Sie es möglicherweise wiederholen. Es ist nicht ideal, aber gleichzeitig gehört es zu Ihrer Aufgabe als leitender Entwickler, zu wissen, wie man Code liest und interpretiert, zum Teil, um diese Art von vergrabenen Fehlern zu lokalisieren.

Meiner Meinung nach konzentrieren Sie sich auf den falschen Teil der Frage. Was ist, wenn Sie den betreffenden Fehler letztendlich nicht reproduzieren können ? Für einen Kunden ist nichts frustrierender, als zu hören: "Ja, wir wissen, dass Sie das Programm zum Absturz gebracht haben, aber wir können es nicht reproduzieren, es ist also kein Fehler." Wenn Ihr Kunde dies hört, interpretiert er es als "Wir wissen, dass unsere Software fehlerhaft ist, aber wir können uns nicht die Mühe machen, die Fehler zu beheben, also drücken Sie einfach die Daumen." Wenn es besser ist, einen gemeldeten Fehler als "nicht reproduzierbar" oder als "nicht reproduzierbar" zu schließen, wir aber einige sinnvolle Änderungen vorgenommen haben, um die Stabilität zu verbessern?


3

Sofern der Fehler nicht offensichtlich, offensichtlich und trivial ist, mit einer sehr spezifischen Fehlermeldung usw., ist es oft sehr schwierig, einen Fehler zu beheben, wenn der Benutzer oder der Betreuer ihn nicht replizieren kann.

Wie würden Sie ihnen auch beweisen, dass der Fehler behoben ist, wenn Sie die Schritte nicht replizieren können?

Das Problem in Ihrem Fall ist, dass der Benutzer auch nicht weiß, wie der Fehler aufgetreten ist, dh auf welchem ​​Bildschirm, um welche Operation auszuführen. Sie haben einfach das Protokoll.

Ich denke, Ihr Standpunkt ist vernünftig. Wenn Sie psychische Kräfte hätten , würden Sie möglicherweise nicht für ein Gehalt arbeiten.

Ich denke, Sie sollten Ihren Vorgesetzten sagen, dass es eine unbekannte Zeit dauern würde, bis Sie den Fehler gefunden haben, ohne ihn reproduzieren zu können, und es gibt überhaupt keine Garantie dafür.

Das Problem wird sein, wenn ein Mitarbeiter von Ihnen den Fehler aus reinem Glück findet und ihn behebt.


3

Nehmen wir es auf das Äußerste und nehmen wir an, dass Sie den Fehler viel früher gefunden haben: in Ihrem Code, als Sie ihn geschrieben haben. Dann hätten Sie keine Bedenken, es genau dort zu reparieren - Sie sehen einen logischen Fehler im Code, den Sie gerade geschrieben haben, er tut nicht das, was Sie wollten. Sie würden nicht das Bedürfnis verspüren, eine ganze Umgebung einzurichten, um zu zeigen, dass es sich tatsächlich um einen Fehler handelt.

Jetzt kommt ein Fehlerbericht. Sie können verschiedene Dinge tun. Eine davon ist, zum Code zurückzukehren und ihn erneut zu lesen. Nehmen wir nun an, dass Sie bei dieser zweiten Lesung den Fehler sofort im Code finden - er tut einfach nicht das, was Sie beabsichtigt haben, und Sie haben es nicht bemerkt, als Sie ihn geschrieben haben. Und es erklärt perfekt den Fehler, der gerade reinkam! Sie machen das Update. Du hast zwanzig Minuten gebraucht.

Hat das den Fehler behoben, der den Fehlerbericht verursacht hat? Sie können sich nicht zu 100% sicher sein (es gab möglicherweise zwei Fehler, die dasselbe verursacht haben), aber wahrscheinlich hat es das getan.

Eine andere Möglichkeit besteht darin, die Konfiguration des Kunden so gut wie möglich zu reproduzieren (einige Arbeitstage) und den Fehler schließlich zu reproduzieren. In vielen Fällen gibt es Zeit- und Parallelitätsprobleme, die bedeuten, dass Sie den Fehler nicht reproduzieren können, aber Sie können viel Zeit versuchen und manchmal sehen, dass das Gleiche passiert. Jetzt beginnen Sie mit dem Debuggen, finden den Fehler im Code, stellen ihn in die Umgebung und versuchen es häufig erneut. Sie sehen den Fehler nicht mehr.

Hat das den Fehler behoben, der den Fehlerbericht verursacht hat? Sie können sich immer noch nicht hundertprozentig sicher sein - erstens haben Sie möglicherweise einen völlig anderen Fehler gesehen als der Kunde, zweitens haben Sie es möglicherweise nicht oft genug versucht, und drittens ist die Konfiguration möglicherweise immer noch ein wenig anders auf diesem System behoben, aber nicht die des Kunden.

Gewissheit ist also auf keinen Fall zu bekommen. Aber die erste Methode ist viel schneller (Sie können dem Kunden auch einen Patch schneller geben), ist viel billiger und, wenn Sie einen klaren Codierungsfehler finden, der das Symptom erklärt, ist es tatsächlich wahrscheinlicher, dass Sie das Problem auch finden.

Es kommt also darauf an. Wenn es billig ist, eine Testumgebung einzurichten (oder besser: ein automatisierter Test, der das Problem aufzeigt), dann tun Sie dies. Aber wenn es teuer ist und / oder die Umstände, unter denen der Fehler auftritt, nicht vorhersehbar sind, ist es immer besser, zuerst den Code zu lesen, um den Fehler zu finden.


Gehen Sie davon aus, dass der Code von Anfang an von mir stammt?
Amphibient

Nach meiner Erfahrung landen Fehlerberichte oft bei dem Typ, der den Code geschrieben hat, aber das ist für meine Antwort nicht wichtig. Sie können auch den Code anderer Leute lesen und Fehler darin erkennen.
RemcoGerlich,

1

Wenn ich die Frage lese, sehe ich keinen grundsätzlichen Widerspruch zwischen Ihrer Position und der Ihres Teams.

  • Ja, Sie sollten sich nach besten Kräften bemühen, das in der Clienteinstellung auftretende Problem zu reproduzieren. Nach besten Kräften sollten Sie jedoch eine Zeitbox dafür definieren, und das Protokoll enthält möglicherweise nicht genügend Daten, um das Problem tatsächlich zu reproduzieren.

    Wenn ja, hängt alles von der Beziehung zu diesem Kunden ab. Es kann sein, dass Sie nichts anderes von ihm haben, um einen Entwickler mit Diagnosewerkzeugen und der Fähigkeit, sie auf dem fehlerhaften System auszuführen, vor Ort zu schicken. Normalerweise sind wir irgendwo dazwischen und wenn die anfänglichen Daten nicht ausreichen, gibt es Möglichkeiten, mehr zu bekommen.

  • Ja, ein erfahrener Entwickler sollte in der Lage sein, den Code zu lesen und den Grund für das Problem wahrscheinlich anhand des Protokollinhalts zu ermitteln. In der Tat ist es oft möglich, einen Komponententest zu schreiben, bei dem das Problem auftritt, nachdem der Code sorgfältig gelesen wurde.

    Das erfolgreiche Verfassen solcher Komponententests ist fast so gut wie die Reproduktion der brechenden Funktionsumgebung. Natürlich ist diese Methode auch keine Garantie dafür, dass Sie etwas finden. Das Verständnis der genauen Abfolge von Ereignissen, die in einigen Multithread-Programmen zu Fehlern führen, kann sehr schwierig sein, wenn Sie nur den Code lesen. Die Fähigkeit, Live-Fehler zu beheben, wird wahrscheinlich kritisch.

Zusammenfassend würde ich für beide Ansätze gleichzeitig versuchen und nach einem Live-System fragen, das das Problem aufweist (und zeigt, dass es anschließend behoben wird), oder nach einem Test einer Unterbrechungseinheit, die das Problem unterbricht (und auch zeigt, dass es nach dem Beheben behoben wird).

Der Versuch, den Code einfach zu reparieren und in freier Wildbahn zu senden, sieht in der Tat sehr riskant aus. In einigen ähnlichen Fällen (in denen der Defekt intern nicht reproduziert werden konnte) habe ich klargestellt, dass der vorgeschlagene Mitarbeiter das Kundenproblem nicht gelöst hat, wenn ein Fix in die Luft ging oder andere unerwartete negative Konsequenzen hatte Es müsste dem Support-Team helfen, das eigentliche Problem zu finden. Einschließlich des Umgangs mit dem Kunden, falls erforderlich.


1

Klingt für mich nach einer detaillierteren Protokollierung.

Das Hinzufügen weiterer Protokolle kann zwar nicht garantieren, dass Sie keine Fehlerbehebung durchführen müssen (oder in diesem Fall die Situation reproduzieren müssen), gibt Ihnen jedoch einen weitaus besseren Einblick in das, was tatsächlich schief gelaufen ist.

Besonders in komplizierten / Threading-Situationen oder in Situationen, in denen Sie keinen Debugger verwenden können, kann das Zurückgreifen auf "debug by printf ()" Ihre einzige Möglichkeit sein. In diesem Fall sollten Sie so viel wie möglich protokollieren (mehr als Sie voraussichtlich benötigen) und ein paar gute Werkzeuge zum Filtern der Spreu vom Weizen haben.


1

Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert und behoben wird, bevor er diagnostiziert und behoben wird?

Da hat es noch niemand klar gesagt: Absolut nicht!

Wie alles in der Softwareentwicklung bedeutet Bugfixing, Zeit, Risiko und Kosten zu berücksichtigen. Ein Gleichgewicht zwischen diesen zu finden, ist die Hälfte der Aufgabenbeschreibung eines Entwicklers.

Einige Fehler sind nicht wichtig genug, um 2 Tage damit zu verbringen, aber wichtig genug, um 10 Minuten damit zu verbringen, sie zu beheben. Andere Fehler sind nicht deterministisch und Sie wissen bereits, dass eine Testumgebung nicht nachweisen kann, dass sie behoben wurden. Wenn das Einrichten der Testumgebung 2 Tage dauert, tun Sie dies bei diesen Fehlern nicht. Stattdessen verbringen Sie die Zeit mit intelligenteren Dingen, z. B. der Suche nach Möglichkeiten zum Einrichten einer Testumgebung in 5 Minuten anstelle von 2 Tagen.

Und natürlich gibt es Fehler, bei denen ein Kunde über 100'000 $ verliert, wenn er sie falsch versteht. Und Fehler, bei denen der Kunde für jede Stunde, in der der Fehler nicht behoben ist, mehr als 100.000 US-Dollar verliert. Sie müssen sich den Fehler ansehen und eine Entscheidung treffen. Pauschalaussagen, um alle Fehler gleich zu behandeln, funktionieren nicht.


0

Sehr gute Frage! Wenn Sie das Problem nicht reproduzieren können, können Sie meiner Meinung nach nicht zu 100% sicher sagen, dass die von Ihnen vorgenommene Fehlerbehebung nicht zu Folgendem führt:

a) Beheben Sie das Problem tatsächlich. b) Erstellen Sie einen weiteren Fehler

Es gibt Zeiten, in denen ein Fehler auftritt und ich ihn behebe und mich nicht darum kümmere, ihn zu testen. Ich weiß zu 100%, dass es funktioniert. Aber bis unsere QA-Abteilung sagt, dass es funktioniert, halte ich es immer noch für möglich, dass noch ein Fehler vorliegt ... oder ein neuer Fehler, der aus dem Fix erstellt wurde.

Wenn Sie den Fehler nicht reproduzieren und dann die neue Version installieren und bestätigen können, dass er behoben ist, können Sie nicht mit 100% iger Sicherheit sagen, dass der Fehler behoben ist.

Ich habe ein paar Minuten lang versucht, mir eine Analogie auszudenken, mit der Sie anderen erklären können, aber mir ist nichts eingefallen. Eine Vasektomie ist ein lustiges Beispiel, aber es ist nicht die gleiche Situation :-)


Nehmen wir zum Beispiel an, man erhält den Bericht, dass ein Programm gelegentlich einige dezimal formatierte Zahlen falsch formatiert, wenn es auf einer französischen Windows-Version installiert ist. eine Suche nach Kultur-Einstellcode zeigt man ein Verfahren entdeckt , die den aktuellen Thread Kultur spart und setzt es InvariantCulturein einer CompareExchangeSchleife, sondern setzt es danach [so dass , wenn die CompareExchangedas erste Mal fehlschlägt, die „gerettet“ Kultur Variable erhalten überschrieben] . Das Reproduzieren der Fehlerumstände wäre schwierig, aber der Code ist eindeutig falsch und könnte das angegebene Problem verursachen.
Supercat

In einem solchen Fall wäre es notwendig, den Fehler zu reproduzieren, oder würde die Tatsache, dass der fragliche Code eindeutig Fehler wie den angegebenen verursachen kann, ausreichen, wenn man den Code auf andere Stellen untersucht, an denen ähnliche Fehlermodi auftreten könnten auftreten?
Supercat

Nun, das ist das Ganze, "es kommt auf das Situationsargument an". Wenn es sich um ein unternehmenskritisches System für Leben oder Tod handelte oder ein Kunde diese Art von Tests erwartete, sollten Sie sich nach besten Kräften bemühen, das Problem zu reproduzieren und zu testen. Ich musste Code auf einen Kundenrechner herunterladen, damit ich Fehler beheben konnte, da wir ein Problem auf unseren Testservern nicht reproduzieren konnten. Es war eine Art Windows-Sicherheitsproblem. Erstellt eine Lösung und jeder ist glücklich. Es ist schwierig, die Testumgebung einzurichten, als den Fehler zu beheben. Dann können Sie den Kunden fragen. Meistens sind sie damit einverstanden, es selbst zu testen.
Jaydel Gluckie

Selbst wenn es bei vermuteten Threading - Problemen gelingt, Dinge so zu verhexen, dass sie genau zum "falschen" Zeitpunkt eintreten, kann man nicht wirklich feststellen, ob das von Ihnen reproduzierte Problem dasselbe ist, das auch von der beobachtet wurde Kunde? Wenn Code einen Fehler aufweist, der dazu führt, dass Dinge mit einem bestimmten Timing nicht funktionieren, und es zumindest theoretisch möglich ist, dass ein solches Timing auftritt, sollte der Code nach meinem Dafürhalten repariert werden, ob man eine Testumgebung verhexen kann oder nicht Die erforderlichen Timings finden statt. In vielen solchen Situationen ...
Supercat

... Test- und Produktionsumgebungen weisen häufig ausreichende Zeitunterschiede auf, so dass es äußerst schwierig und nicht besonders informativ ist, zu beurteilen, ob bestimmte schlechte Zeiten tatsächlich auftreten können. Es ist wichtig, Orte zu untersuchen, die möglicherweise zeitlich empfindlich sind, um sicherzustellen, dass dies nicht der Fall ist, da Tests auf zeitliche Empfindlichkeit häufig viele falsche Negative aufweisen.
Superkatze

0

[Fehler in Bezug auf] gleichzeitiger Datenbankzugriff, Cluster-Implementierung, Multithreading

Ist es sinnvoll, darauf zu bestehen, dass jeder Fehler reproduziert und behoben wird, bevor er diagnostiziert und behoben wird?

Ich würde nicht zu viel Zeit damit verbringen, es zu reproduzieren. Dies scheint ein Synchronisationsproblem zu sein, und diese werden häufiger durch Überlegungen (ausgehend von Protokollen wie dem, in dem Sie das Subsystem bestimmen müssen, in dem das Problem auftritt) als durch die Möglichkeit, es zu reproduzieren und mit einem Debugger anzugreifen, gefunden . Nach meiner Erfahrung kann es ausreichen, die Optimierungsstufe des Codes zu reduzieren oder manchmal zusätzliche Instrumente zu aktivieren, um eine ausreichende Verzögerung oder das fehlende Synchronisationsprimitiv hinzuzufügen, um zu verhindern, dass sich der Fehler manifestiert.

Ja, wenn Sie keine Möglichkeit haben, den Fehler zu reproduzieren, können Sie nicht sicher sein, dass Sie ihn beheben. Wenn Ihr Kunde Ihnen jedoch nicht die Möglichkeit gibt, diese zu reproduzieren, suchen Sie möglicherweise nach etwas Ähnlichem mit der gleichen Konsequenz, aber einer anderen Ursache.


0

Beide Aktivitäten (Codeüberprüfung und Testen) sind notwendig, beide reichen nicht aus.

Sie könnten Monate damit verbringen, Experimente zu erstellen, um den Fehler zu korrigieren, und kommen nie weiter, wenn Sie sich den Code nicht ansehen und eine Hypothese aufstellen, um den Suchraum einzugrenzen. Sie könnten monatelang in Ihren Nabel blicken und versuchen, einen Fehler im Code zu visualisieren. Sie könnten sogar denken, Sie hätten ihn einmal, zweimal, dreimal gefunden, nur um den immer ungeduldiger werdenden Kunden sagen zu lassen: "Nein, der Fehler ist immer noch da. "

Einige Entwickler sind in einer Aktivität (Codeüberprüfung im Vergleich zum Erstellen von Tests) relativ besser als in der anderen. Ein perfekter Manager wägt diese Stärken beim Zuweisen von Fehlern ab. Ein Teamansatz kann sogar noch fruchtbarer sein.

Letztendlich sind möglicherweise nicht genügend Informationen vorhanden, um den Fehler erneut zu beheben, und Sie müssen eine Weile warten, bis ein anderer Kunde ein ähnliches Problem feststellt, sodass Sie einen besseren Einblick in das Konfigurationsproblem erhalten. Wenn der Kunde, der den Fehler gesehen hat, wirklich möchte, dass er ihn behebt, wird er mit Ihnen zusammenarbeiten, um weitere Informationen zu sammeln. Wenn dieses Problem nur einmal aufgetreten ist, ist es wahrscheinlich kein Fehler mit hoher Priorität, auch wenn der Kunde wichtig ist. Manchmal ist es klüger, einen Fehler nicht zu beheben, als stundenlang nach einem wirklich undurchsichtigen Defekt mit nicht genügend Informationen zu suchen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.