Wie gehe ich vor, um einen nicht reproduzierbaren / zufällig auftretenden Fehler zu beheben?


11

Wir haben eine mehrsprachige Website, auf der vor einigen Tagen ein Fehler entdeckt wurde. Es wurden andere Sprachdaten in einer anderen Sprache angezeigt, und es wurde auch die Mischung von Daten wie der englischen Sprache ausgewählt, aber es wurden auch andere Sprachdaten auf der Seite angezeigt und umgekehrt. Es macht es selten, ist aber auf der Website vorhanden. Das Durchgehen des Codes hilft auch nicht, da dies nicht immer vorkommt.

Irgendwelche Vorschläge, um das Problem rechtzeitig zu finden? Ich frage hier nach Strategien.


4
Beginnen Sie, den Code nach Situationen zu
durchsuchen, in

Antworten:


20

Der erste Schritt ist , um zu versuchen und zu charakterisieren , was kann diese Art von Problem verursachen. Da dies mit der Auswahl der richtigen Sprache für Codeabschnitte zusammenhängt, sollten Sie zunächst Folgendes berücksichtigen:

  • Wie wird die Sprache erkannt? Basiert es auf Informationen aus der HTTP-Anfrage? Basiert es auf Sitzungsinformationen? Oder basiert es auf Datenbankfeldern? Kann dies im Wesentlichen ein Problem sein, das damit zusammenhängt, wie Ihre App die Sprache für jeden Abschnitt auswählt?
  • Wie wird die Sprache angezeigt? Ziehen Sie aus einer Eigenschaftendatei oder einer Datenbank? Ist es möglich, dass der Verweis auf die richtige Sprache irgendwie verloren geht? Ist die gemischte Sprache, die Sie sehen, immer die Standardeinstellung für die Site?
  • Gibt es eine Korrelation zur Clientumgebung? Dies hängt mit der ersten Kugel zusammen, geht aber etwas weiter. Ich hatte seltsame Rendering-Probleme aufgrund von Downstream-Caching-Proxys. In der Regel handelt es sich bei diesen Arten von Problemen um eine ganze Seite, die veraltet ist oder die Seite einer Person anderen Benutzern bereitstellt (was peinlich war).
  • Verwenden Sie einen Thread Local-Wert? Wenn eine Anfrage von mehr als einem Thread bearbeitet wird, enthält der lokale Wert des Threads unterschiedliche Informationen, basierend auf dem Thread, der gerade arbeitet. In einer Webserverumgebung können Sie nicht davon ausgehen, dass der Thread, für den Sie mit der Verarbeitung begonnen haben, derselbe Thread ist, für den Sie die Verarbeitung abgeschlossen haben - es sei denn, dies ist Teil der Spezifikation für Ihre Plattform. Serverschreiber haben festgestellt, dass sie mehr Anforderungen gleichzeitig verarbeiten können, wenn sie einen kleinen Pool von Threads wiederverwenden und diese in Blöcken multiplexen. Selbst wenn Sie vom Anfang bis zum Ende einer Anforderung einen Thread haben, multiplext der Server möglicherweise gleichzeitig andere Anforderungen an diesen Thread. Anstelle von Thread-Locals sollten Sie diesen Wert an die Anforderungs- oder Sitzungsattribute binden.

Nun, wenn Sie die gekennzeichnet haben Möglichkeiten , was schief gehen kann, wird es Zeit , um sicherzustellen , haben Sie die Daten , die Sie brauchen , um zu versuchen und herausfinden, was tat schief gehen.

  • Verwenden Sie eine umfangreiche Protokollierung in den Problembereichen. Dies ist ein Ort, an dem ein Tool wie Log4J oder Log4Net wirklich glänzen kann. Mit diesem und ähnlichen Protokollierungsframework können Sie die Protokollierung für bestimmte Kategorien aktivieren und gleichzeitig das Rauschen für alles andere verringern - indem Sie eine Konfigurationsdatei ändern. Sie möchten neue Protokollierungsanweisungen einführen, um herauszufinden, ob das, was Sie vermuten, möglicherweise das Problem ist. Stellen Sie außerdem sicher, dass Ihre HTTP-Zugriffsprotokolle alle gewünschten Informationen zu jeder Anforderung enthalten (Cookies, http-Header-Parameter usw.).
  • Versuchen Sie, das Problem zu simulieren. Wie ist die Belastung des Servers zum Zeitpunkt des Auftretens, da dies sporadisch geschieht? Werden Sie von mehreren gleichzeitigen Anfragen aus verschiedenen Sprachen getroffen? Versuchen Sie in diesem Fall, diese Art von Last in Ihrer Testumgebung zu simulieren. Möglicherweise benötigen Sie ein JMeter-ähnliches Tool. Sie möchten auch IP-Adressen für Ihre gefälschten Clients fälschen können. Denken Sie daran, dass IP-Adressen aufgeteilt sind, damit Sie anhand der ersten beiden Segmente der Adresse herausfinden können, auf welchem ​​Land / welcher Region die IP basiert.
  • Das Problem wird in Ihrer Testumgebung genauso sporadisch sein, aber wenn Sie sich auf Ihre eigentliche Ursache beschränken, können Sie die Ergebnisse verzerren, damit es häufiger auftritt als in freier Wildbahn. Darüber hinaus können Sie die Protokolldateien einfacher überprüfen und versuchen, daraus zu lernen.
  • Es ist ein iterativer Prozess, seien Sie also geduldig. Sie müssen die Art der Last ermitteln, von der Sie glauben, dass sie den Fehler reproduziert, die Protokolle überprüfen und Ihre Tests basierend auf den gefundenen Ergebnissen verfeinern. Das Wichtigste ist , das Problem zu identifizieren. Widerstehen Sie also dem Drang, einige einfache Korrekturen vorzunehmen, die das eigentliche Problem möglicherweise nur seltener verursachen.

Wenn Sie das Problem so weit eingegrenzt haben, dass Sie wissen, wie es reproduziert werden kann und was es verursacht, schreiben Sie den kleinsten automatisierten Test, um das Problem im Code zu erzwingen. Wenn Sie das Problem auf eine Klasse eingegrenzt haben oder zwei Klassen nicht richtig zusammenarbeiten, reproduzieren Sie es auf dieser Ebene. Sie sollten nicht 100 Threads erzeugen müssen, um dies zu tun. Führen Sie einfach den kleinsten Test durch, der dazu führen kann, dass das Problem in 100% der Fälle auftritt.

Jetzt können Sie das Problem beheben und sich darauf verlassen, dass es Sie nicht wieder beißt.


10

Der Fehler ist nicht reproduzierbar. Sie haben nur noch nicht herausgefunden, wie Sie es reproduzieren können.

Kein Fehler ist zufällig, es sei denn, Sie lösen eine Ausnahme aus, die auf dem Rückgabewert einer Random () - Anweisung basiert.

Ich weiß, dass dies wie eine Semantik erscheint, aber es ist mental beruhigend, sich das selbst zu erzählen.

Es ist sehr schwer und frustrierend herauszufinden, wie man einen Fehler wiedergibt, der nur aufgrund komplexer Rennbedingungen oder dergleichen auftritt.

Wie man es findet, würde ich die Anwendung an Stellen aktivieren / hinzufügen, die Ihnen weitere Informationen geben könnten.

Als nächstes teilen Sie den Personen, die den Fehler sehen (ob es sich um Entwickler, Qualitätssicherung oder Endbenutzer handelt), mit, dass sie ihn melden sollen, sobald sie ihn mit der Zeit sehen, zu der er aufgetreten ist, und konsultieren Sie dann Ihre Protokolle. Fragen Sie sie nach anderen Informationen, und der Fehler kann nur aufgrund der Interaktion mehrerer verschiedener Systeme oder aufgrund einer Rennbedingung auftreten

Hoffentlich finden Sie einen Hinweis.


Selbst Random () -Aufrufe sind nicht wirklich zufällig, es sei denn, sie werden von einem Hardware-Generator für weißes Rauschen abgeleitet. Sie sind pseudozufällig, was bedeutet, dass die Zahlen mathematisch in einer möglichst zufälligen Reihenfolge verteilt sind. Wenn Sie jedoch mit demselben "Startwert" beginnen, erhalten Sie jedes Mal dieselbe Antwort.
Berin Loritsch

1
@Berin: Ich weiß.
Gilles

+1 für "Sie haben nur noch nicht herausgefunden, wie Sie es reproduzieren können." Alle Fehler haben eine Grundursache, sonst würden sie nicht auftreten.
Mike S

1
Es muss nicht zufällig sein (), Dinge, die zeitabhängig sind, insbesondere solche, die einen unzulässigen Zugriff auf eine gemeinsam genutzte Ressource beinhalten, können sehr schwer zu reproduzieren sein.
Loren Pechtel

2
@ Gilles: Außer sie sind möglicherweise nicht deterministisch für alles, was Sie vernünftigerweise messen können. (Sagen
wir

5

Sie können versuchen, Stellen in Ihrem Code zu finden, an denen Sie erkennen können, dass das Problem aufgetreten ist (z. B. inkonsistente Parameter in einer Methode), die Überprüfungen zu Ihrem Code hinzufügen und zusätzliche Informationen zum Debug-Protokoll hinzufügen lassen (z. B. eine Stapelverfolgung, Objekte) zur Sitzung hinzugefügt usw.)

Wenn Sie dies tun, können Sie mit etwas Glück Informationen über die Ereignisse erfassen und den Weg zurück zum Problem ableiten.


2

Automatisierung sollte helfen, wenn es die gleichen Schritte zur Reproduktion sind, die manchmal fehlschlagen, automatisieren Sie dies und setzen Sie sie in eine Schleife. Laufen Sie 50.000 Mal und es ist sehr wahrscheinlich, dass es auftritt.


Das Ereignis ist nicht zufällig, es scheint nur zufällig zu sein. Wenn Sie dies tun, wird es möglicherweise angezeigt, Sie erhalten jedoch nur sehr wenige Informationen darüber, warum es angezeigt wurde .
Josh K

1
@Josh - Wenn er es nicht reproduzieren kann, ist dies möglicherweise eine gute Möglichkeit, dies zu tun und beispielsweise einen Stack-Trace mit Debug-Symbolen zu erhalten. Ich denke, das ist ein großartiger erster Schritt - aus erster Hand zu sehen
Kieren Johnstone

Sie gehen davon aus, dass es einen Stapel gibt und dieser erhältlich ist. Er hat uns keine technischen Informationen über die Anwendung gegeben oder wie zugänglich sie für das Debuggen unter dieser Art von Last ist. Dies ist keine Debugging-Strategie , sondern schlägt mit einem Hammer darauf ein, den genauen Moment zu erfassen, in dem er bricht.
Josh K

@Josh - meine reale Erfahrung zeigt mir, dass das Wertvollste bei der Untersuchung / Behebung eines Fehlers darin besteht, ihn aus erster Hand zu sehen. Ob es etwas mit Timing ist, das Sie sehen können, eine Stapelverfolgung, etwas in den Protokollen oder irgendetwas anderes. Wenn möglich, haben mich scheinbar zufällig auftretende Probleme in einer Schleife sehr schnell dorthin gebracht. Wenn Sie eine andere Idee haben, posten Sie sie als Antwort um Himmels willen - dies ist eine gültige Methode und eine gültige Antwort.
Kieren Johnstone

Ich bin anderer Meinung und ich glaube, Berins Antwort ist der richtige Weg, um dies zu lösen.
Josh K

1

Versuchen Sie, Muster zu finden, um die Bedingungen zu bestimmen, unter denen sich dieses Problem manifestiert. Das sollte Sie auf die Abschnitte Ihres Codes hinweisen, die fehlschlagen (oder sich inkonsistent verhalten).


Keine Scheiße ..............
Theringostarrs

0

Können Sie erkennen , wenn das Problem wird auftreten? Wenn ja, können Sie Informationen über den Status des Systems zu diesem Zeitpunkt zuverlässig sichern?

Wenn die Antwort auf diese beiden Fragen Ja lautet, instrumentieren Sie Ihren Code, um so viele Informationen wie möglich zu protokollieren, wenn der Fehler tatsächlich auftritt, und warten Sie dann.

Dies ist kein Ersatz für das, was andere vorgeschlagen haben (Sie müssen noch überlegen, wie der Code in den Status gelangen kann, den Sie sehen), aber solange Sie den Fehler nicht nach Belieben reproduzieren können, Es ist eine gute Idee, die Gelegenheiten, in denen es auftritt, nicht zu verschwenden.

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.