Lösung für gelegentliche Abstürze des Positionierungs-Hintergrunddienstes unter Linux

Lösung für gelegentliche Abstürze des Positionierungs-Hintergrunddienstes unter Linux

Problembeschreibung

Im aktuellen Hintergrunddienst wurde eine neue Funktion hinzugefügt, um die Anforderungsdaten einer bestimmten Anweisung auf der Festplatte zu speichern. In der spezifischen Implementierung wird eine Mitgliedsvariable verwendet, um den Proxy-Header der Anforderungsnachricht zu speichern, der zerstört wird, wenn eine Antwort empfangen und die Nachrichtenverwaltungsklasse freigegeben wird. Laut Testrückmeldungen kommt es gelegentlich zu Abstürzen des Dienstes.

Problemanalyse

Die rel-Version des Programms läuft in der Testumgebung. Da die Debuginformationen (-g) entfernt und die O3-Level-Optimierung beim Kompilieren aktiviert wurde, ist aus dem Crash Dump Stack nur der Call Stack des Programmabsturzes ersichtlich. Die Funktionsparameter sind wegoptimiert. Da hier kein Log vorhanden ist, können wir uns nur andere Möglichkeiten zur Reproduktion überlegen. Es wird vermutet, dass der Absturz durch wiederholtes Loslassen von Zeigern verursacht wurde, daher werden wir dies weiter analysieren.

Aus dem Aufrufstapel der rel Version können wir nur den letzten zerstörten Funktionsaufruf sehen. Im tatsächlichen Code gibt es jedoch zwei zerstörte Funktionsaufrufeinträge. Warum stimmt die im Dump angezeigte Reihenfolge des Aufrufstapels nicht mit dem tatsächlichen Code überein? Es wird vermutet, dass die O3-Optimierung aktiviert und die Funktion integriert ist.

Zur Analyse wurden folgende Experimente durchgeführt:

void test_dump()
{
	int* p = NULL;
	*p = 2; // Dump ausführen
}

void test_f2(int b)
{
	b += 1;
	test_dump();
}

void test_f1(int a)
{
	ein+=1;
	test_f2(a);
}

int main()
{
 test_f1(1);
	gebe 0 zurück;
}

Lösen Sie im Debug- und Rel-Modus einen Absturz aus und verwenden Sie gdb, um die Stapelinformationen wie folgt auszugeben:

Fazit : Im Rel Modus wird die aufrufende Funktion durch eine Optimierung auf O3-Ebene integriert. Wenn beim Zurückverfolgen vom Absturzpunkt aus mehrere mögliche Einstiegspunkte vorhanden sind, können dump Informationen allein nicht bestätigen, welcher Einstiegspunkt den Absturz ausgelöst hat.

Aufbau einer Testumgebung

Durch die Analyse des Codes wissen wir, dass wir zum Auslösen möglicher Mehrfachfreigaben ein Szenario konstruieren müssen, in dem Erstellung und Löschung gleichzeitig erfolgen.

Erstellung: Sie können das Testtool verwenden, um bestimmte Anweisungen in hoher Frequenz und zu einem festgelegten Zeitpunkt zu senden, um den Erstellungsprozess auszulösen. Zerstörung: In der geplanten Aufgabe können Sie einen ungültigen Status melden, um den Zerstörungsprozess auszulösen. Um die Absturzreproduktionsgeschwindigkeit zu beschleunigen, müssen die Erstellungs- und Zerstörungsgeschwindigkeiten angemessen aufeinander abgestimmt sein. Wenn die Zerstörung zu schnell erfolgt, ist es unmöglich, in den Erstellungsprozess einzusteigen. Nach Analyse und Experimenten haben wir das Testtool schließlich so eingestellt, dass es alle 50 Millisekunden sendet, und den Hintergrunddienst so, dass er alle 50 ms einen ungültigen Status meldet.

Um die Ursache des Absturzes weiter zu verifizieren, fügen Sie Schlüsselpfaden wie dem Zerstörungsvorgang Protokolle hinzu und starten Sie Rel Version zur Reproduktion. Nach einer langen Testphase haben wir 2 wertvolle Crashdumps und entsprechende Protokolle erhalten. Die Reproduktion jedes Dumps dauert 2,5 Stunden oder sogar länger. Dies deutet darauf hin, dass dieses Problem sporadisch auftritt und wahrscheinlich mit Konflikten bei mehreren Threads zusammenhängt. Der Zeitaufwand zur Reproduktion des Problems ist etwas hoch, aber der erhaltene Dump und das Protokoll reichen aus, um das Problem zu lokalisieren.

Protokollanalyse

Für denselben Back-End-Dienst werden Protokolle verschiedener Geschäftsmodule in verschiedenen Protokolldateien verteilt. Bei der Analyse müssen die Protokolle jedes Teils aggregiert werden, um die Reproduktion des gesamten Prozesses zu erleichtern. Während der Aggregation können die letzten Protokollzeilen jedes Moduls nach Bedarf abgefangen werden. Jedes Protokoll enthält normale und abnormale Protokolle, die in einer einzigen Datei aggregiert und dann mit dem Code für eine zeilenweise Korrelationsanalyse kombiniert werden.

Während des Analyseprozesses stieß ich auf einige Fragen zum Framework und erhielt Antworten, indem ich die entsprechenden Kollegen befragte. Beim Empfangen einer Nachricht stellt das aktuelle Framework zum Senden und Empfangen von Nachrichten die Nachricht zuerst in die Nachrichtenwarteschlange des Thread-Pools, weckt den Thread über das Semaphor, ruft die Nachricht aus der Nachrichtenwarteschlange ab und holt die Verarbeitungsfunktion zur Verarbeitung aus der Nachricht heraus.
Bei der Verarbeitung unterschiedlicher Nachrichten auf der Anwendungsebene können bei der Verarbeitung derselben Variablen Race Conditions auftreten. Durch die Analyse der freigegebenen Zeiger wird festgestellt, dass für die normalen freigegebenen Zeiger bestimmte Regeln gelten. Wenn ein Absturz ausgelöst wird, unterscheidet sich der Wert des freigegebenen Zeigers offensichtlich vom normalen Wert.

Erfahrungszusammenfassung: Wenn eine Dump-Datei gefunden wird, überprüfen Sie den Zeitpunkt, zu dem die Dump-Datei generiert wurde, und legen Sie das Protokoll und die ausführbare Datei zu diesem Zeitpunkt zusammen mit der Dump-Datei in einem separaten Ordner zur späteren Analyse ab. Denn es können die aktuellen Logdateien und ausführbaren Dateien gelöscht und aktualisiert werden. Jede Problemlösung ist ein tieferes Verständnis des bestehenden Systems. Verwenden Sie beim Erstellen einer Reproduktionsumgebung die Rel-Version und nutzen Sie Protokolle nur zum Bestätigen des Programmflusses, nicht von Haltepunkten. Unter Linux können Sie keine verschachtelten Mutexe verwenden, da dies den Zweck des Designs zunichte macht und potenzielle Deadlocks schwerer zu erkennen sind. Es ist besser, Fehler frühzeitig zu erkennen, als sie später zu entdecken. Machen Sie mutige Annahmen und überprüfen Sie diese sorgfältig, dann wird sich der Sieg irgendwann anbahnen.

Dies ist das Ende dieses Artikels zum Beheben gelegentlicher Abstürze von Hintergrunddiensten unter Linux. Weitere Informationen zum Auffinden von Abstürzen von Hintergrunddiensten unter Linux finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

<<:  Notieren Sie eine Falle bei der Aktualisierung der MySQL-Update-Anweisung

>>:  So zeigen Sie JSON-Daten in HTML an

Artikel empfehlen

Tutorial-Diagramm zur Installation von Zabbix2.4 unter Centos6.5

Die feste IP-Adresse des Centos-DVD1-Versionssyst...

Vue implementiert Benutzeranmeldung und Token-Verifizierung

Im Falle einer vollständigen Trennung von Front-E...

TypeScript-Aufzählungstyp

Inhaltsverzeichnis 1. Übersicht 2. Digitale Aufzä...

SQL Get gespeicherte Prozedur gibt Datenprozessanalyse zurück

Dieser Artikel stellt hauptsächlich die Analyse d...

Analyse gängiger Anwendungsbeispiele von MySQL-Prozessfunktionen

Dieser Artikel veranschaulicht anhand von Beispie...

Vue und React im Detail

Inhaltsverzeichnis 1. Panorama II. Hintergrund 1....

Javascript Blob-Objekt zum Erzielen eines Dateidownloads

Inhaltsverzeichnis veranschaulichen 1. Blob-Objek...

Detaillierte Erläuterung der Kapselung von JavaScript-Animationsfunktionen

Inhaltsverzeichnis 1. Prinzip der Animationsfunkt...

In diesem Artikel erfahren Sie mehr über NULL in MySQL

Inhaltsverzeichnis Vorwort NULL in MySQL 2 NULL b...

Nginx-Dienst 500: Interner Serverfehler einer der Gründe

500 (Interner Serverfehler) Auf dem Server ist ei...

So laden Sie das JAR-Paket über die Webseite auf Nexus hoch

Wie lädt man das JAR-Paket in ein privates Lager ...