Debugge Abstürze/Hänger unter Linux

Wir tun unser Bestes, um den Server so stabil und zuverlässig wie möglich zu machen. Dennoch kann es vorkommen, dass der Server unter bestimmten Bedingungen abstürzt, die bei unseren Tests nie vorkommen, sei es durch unterschiedliche Timings, Druckerergebnisse oder Konfigurationen. Damit das klar ist, ich meine nicht nur einen Druck, der aufhört abbricht, oder einen erneuten Verbindungsaufbau in deinem Webbrowser. Ich meine, dass die Backend-Server-Instanzen abstürzen. Wenn das passiert, siehst du in /var/log/syslog etwas wie

Jul 13 23:14:59 Repetier-Server kernel: [85421.242500] Alignment trap: not handling instruction e19c2f9f at [<76db67d4>]
Jul 13 23:14:59 Repetier-Server kernel: [85421.242515] Unhandled fault: alignment exception (0x001) at 0x72740061
Jul 13 23:14:59 Repetier-Server kernel: [85421.242529] pgd = b1820000
Jul 13 23:14:59 Repetier-Server kernel: [85421.242545] [72740061] *pgd=318c0835, *pte=3abf679f, *ppte=3abf6e7f
Jul 13 23:14:59 Repetier-Server systemd[1]: RepetierServer.service: Main process exited, code=killed, status=6/ABRT
Jul 13 23:14:59 Repetier-Server systemd[1]: RepetierServer.service: Unit entered failed state.
Jul 13 23:14:59 Repetier-Server systemd[1]: RepetierServer.service: Failed with result 'signal'.
Jul 13 23:14:59 Repetier-Server systemd[1]: RepetierServer.service: Service has no hold-off time, scheduling restart.
Jul 13 23:14:59 Repetier-Server systemd[1]: Stopped Repetier-Server 3D Printer Server.
Jul 13 23:14:59 Repetier-Server systemd[1]: Starting Repetier-Server 3D Printer Server...
Jul 13 23:15:00 Repetier-Server systemd[1]: Started Repetier-Server 3D Printer Server.

Dies kann zu einem Druckabbruch oder einem Verbindungsabbruch im Webbrowser führen. Wie du siehst, starten wir den Server nach einem Absturz neu. Ohne einen Syslog-Test wirst du also nie erfahren, ob es sich um einen Absturz oder ein Verbindungsproblem handelt.

Um das Problem mit der nächsten Version lösen zu können, müssen wir die Stelle finden, an der der Absturz passiert ist. Um dies herauszufinden, muss der Server im Debugger laufen. Hier definieren wir also die Schritte und die Informationen, die wir benötigen, um die Problemquelle zu finden. All dies wird in einer Linux-Konsole durchgeführt. Wenn du einen Raspberry Pi oder ähnliches verwendest, kannst du dies über eine SSH-Verbindung z.B. mit PuTTY tun. Auf normalen Linux-Versionen kannst du einfach die Konsolenanwendung öffnen.

Als erstes muss der GNU-Debugger gdb installiert werden. Auf Debian-Systemen installiere diesen einfach mit

sudo apt-get update
sudo apt-get install gdb

Once it is installed we will start gdb and connect to the existing Repetier-Server. To do so we need the PID of the server. We get this like this:

ps aux | grep tier
repetie+   928  0.6  2.9 260784 29236 ?        Ssl  Jul13   9:28 /usr/local/Repetier-Server/bin/RepetierServer -c /usr/local/Repetier-Server/etc/RepetierServer.xml --daemon
pi       23206  0.0  0.0   1376   376 pts/1    S+   12:37   0:00 tail -f /var/lib/Repetier-Server/logs/server.log
root     27250  0.0  0.0   2064   508 pts/2    S+   12:53   0:00 grep --color=auto tier

Sieh dir die Zeile mit /usr/local/Repetier-Server/bin/RepetierServer an und merke dir die erste Zahl, hier 928, die die PID ist. Führe nun gdb aus

sudo gdb
attach 928
set logging on

In diesem Moment wird der Prozess angehalten und du kannst ihn analysieren. Nun hängt es davon ab, welches Problem du debuggen möchtest. Wenn du einen Absturz debuggen willst, der später auftreten könnte, fahre einfach mit dem Senden von „c“ fort und sobald der Server abstürzt, wird er im Debugger angehalten. Es ist wichtig, die Konsole offen zu halten. Wenn sie geschlossen wird, kann der Server angehalten oder sogar gestoppt werden. Bei SSH bedeutet dies, dass das öffnende Betriebssystem (Windows) nicht in den Ruhezustand gehen sollte. Wenn der Server läuft, aber nicht reagiert, so dass du glaubst, er hänge aus irgendeinem Grund, fahre direkt mit der Analyse fort:

Der erste Schritt ist die Überprüfung des aktiven Threads durch Senden von bt:

(gdb) bt
#0  __libc_do_syscall () at ../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47
#1  0xf749f4ae in do_sigwait (set=, set@entry=0xffe3ef04, sig=sig@entry=0xffe3ef84) at ../sysdeps/unix/sysv/linux/sigwait.c:61
#2  0xf749f50a in __sigwait (set=0xffe3ef04, sig=0xffe3ef84) at ../sysdeps/unix/sysv/linux/sigwait.c:96
#3  0x0050e0a0 in Poco::Util::ServerApplication::waitForTerminationRequest() ()
#4  0x002fc080 in repetier::RepetierServerApplication::main(std::vector<std::string, std::allocator > const&) ()
#5  0x00501886 in Poco::Util::Application::run() ()
#6  0x0050e3e0 in Poco::Util::ServerApplication::run(int, char**) ()
#7  0x002fabc6 in main ()

Im Falle eines Absturzes zeigt dies, wo es zum Absturz gekommen ist und welche Funktionen welche aufgerufen haben, um dies zu verursachen.

Besonders im Fall eines Hängers ist es auch wichtig, die Rückverfolgung aller Threads zu erhalten, also führe folgendes aus:

(gdb)thread apply all bt

Dies ergibt eine sehr lange Liste mit Informationen zu allen Threads. Besonders wenn du viele Reloads gemacht hast.

Um das Problem, das du hast, zu finden und zu lösen, benötigen wir Folgendes:

  • Was hast du gemacht, als es passiert ist?
  • Jede Meldung, die du in gdb siehst, warum es aufgehört hat.
  • Backtrace des aktiven Threads
  • Backtrace aller Threads
  • Wenn das Problem nur bei bestimmten Dateien auftritt, sollten auch diese Dateien beigefügt werden.
  • Die letzten 100 Zeilen von /var/lib/Repetier-Server/logs/server.log

Durch die Aktivierung der Protokollierung wird die gesamte Ausgabe in die Datei gdb.txt geschrieben. Es besteht also keine Notwendigkeit, die Ausgabe zu erfassen und in eine Datei zu kopieren. Kopiere einfach die Datei aus der gdb-Sitzung, die alles Notwendige enthält. Schicke all dies an repetierdev@gmail.com und wir werden versuchen, die Ursache zu finden und das Problem in der nächsten Version zu beheben.