Univention Bugzilla – Bug 27534
SegFault des Modulprozess beim Reinitialisieren
Last modified: 2016-01-25 15:05:49 CET
Wenn ein Computerraum ausgewählt ist und es wird daraufhin 'Beaufsichtigung reinitialisieren' ausgewählt stirbt der Modul mit einem SegFault. Dies ist zumindest der Fall wenn dies schnell (<= 5 Sekunden) nach dem Öffnen des Raumes durchgeführt wird. Im gdb ist dann folgender Trace zu sehen: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fdd3cdc6700 (LWP 1463)] 0x00007fdd4f365cdc in QMutex::lock (this=0x7fdd380604b0) at thread/qmutex.cpp:150 150 if (d->recursive) { Current language: auto The current source language is "auto; currently c++". (gdb) bt #0 0x00007fdd4f365cdc in QMutex::lock (this=0x7fdd380604b0) at thread/qmutex.cpp:150 #1 0x00007fdd4f36a999 in QThreadPrivate::finish (arg=<value optimized out>) at thread/qthread_unix.cpp:270 #2 0x00007fdd4f36ae1d in ~__pthread_cleanup_class (arg=0x7fdd380009d0) at /usr/include/pthread.h:535 #3 QThreadPrivate::start (arg=0x7fdd380009d0) at thread/qthread_unix.cpp:253 #4 0x00007fdd51cfa8ca in start_thread (arg=<value optimized out>) at pthread_create.c:300 #5 0x00007fdd50bcb86d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #6 0x0000000000000000 in ?? () (gdb) print d $1 = (QMutexPrivate *) 0x0
Ich habe dazu einen iTALC-Bug angelegt: https://sourceforge.net/tracker/?func=detail&aid=3534527&group_id=132465&atid=724375
Created attachment 4436 [details] Might help a little Der Patch zögert die Verwendung von terminate heraus, was laut der QT-Dokuementation möglichst nicht eingesetzt werden soll. Ob es hilft ist bis jetzt nicht bewiesen. Es wird höchstens die Anzaal der Abstürze verringern.
Beim Debugging hat sich herausgestellt, dass das terminate() nicht sofort den Thread beendet. Wann dieser beendet wird, ist abhängig von der Threadimplementierung des Betriebssystems. Im konkreten Fall wurde 1000ms auf die Beendigung des Threads gewartet. Da dies nicht erfolgreich war, wurde der Thread per terminate() "beendet" und sofort mit dem Destruktor der Klasse ItalcVncConnection der Speicher freigegeben. In einigen Fällen lief der Thread danach noch und hat auf bereits freigegebenen Speicher zugegriffen, was zum SIGSEGV geführt hat. Nach dem terminate() wird jetzt solange mit wait() gewartet, bis der Thread sich wirklich beendet hat. Im Test war der Fehler damit nicht mehr zu reproduzieren. Die QT-Doku empfiehlt dieses Vorgehen auch: "Terminates the execution of the thread. The thread may or may not be terminated immediately, depending on the operating system's scheduling policies. Listen for the terminated() signal, or use QThread::wait() after terminate(), to be sure." (Quelle: http://qt-project.org/doc/qt-4.8/qthread.html#terminate)
(In reply to comment #3) > Nach dem terminate() wird jetzt solange mit wait() gewartet, bis der Thread > sich wirklich beendet hat. Im Test war der Fehler damit nicht mehr zu > reproduzieren. Die QT-Doku empfiehlt dieses Vorgehen auch: Das reichte leider nicht aus. Es hat sich hier um ein Python-spezifisches Problem gehandelt, was nur durch unsere Python-Bindings hervorgerufen wurde. iTALC wurde jetzt so gepatcht, dass es eine shutdownAndDestroyLater() Funktion in der ItalcVncConnection-Klasse gibt. Nach der Instantiierung durch die Python-Bindings wird über sip.transferto($OBJ, None) die Verantwortung für das Aufräumen des Speichers/des Objektes an C++/QT übergeben. Der Python-Wrapper fühlt sich an anschließend nicht mehr dafür berufen, über den Garbage Collector das Objekt wegzuräumen. Wenn in ITALC_Computer die Funktion __del__() aufgerufen wird, setzt diese noch den ItalcVncConnection::shutdownAndDestroyLater() Aufruf ab. Die VncConnection-Klasse fährt anschließend über stop() den internen Thread herunter und ruft die geerbte QT-Member-Funktion deleteLater() auf, um sich zu einem späteren Zeitpunkt löschen zu lassen. Das hat im Test bisher sehr gut funktioniert.
Created attachment 5161 [details] Testskript für regelmäßigen Raumwechsel Das angehängte Testskript meldet sich an der UMC an, startet einen Modulprozess und wechselt dann immer zwischen zwei Räumen hin und her. Changelogeintrag fehlt noch
Changelog-Eintrag wurde erstellt.
Die Änderungen funktionieren, ein Absturz von iTalc konnte nicht mehr provoziert werden. (In reply to comment #6) > Changelog-Eintrag wurde erstellt. OK (In reply to comment #1) > Ich habe dazu einen iTALC-Bug angelegt: > > https://sourceforge.net/tracker/?func=detail&aid=3534527&group_id=132465&atid=724375 Ist geschlossen, da dies an unseren Python-bindings lag.
*** Bug 31213 has been marked as a duplicate of this bug. ***
It seems that under specific circumstances the latest changes in the iTalc bindings cause the module process to hang. This happened several times when starting a new exam. The computerroom/acquire command that is sent before querying all computers in the room (computerroom/query) hanged: > ... > 28.02.13 07:13:54.087 PARSER ( INFO ) : UMCP REQUEST 136203203401011-1203 parsed successfully > 28.02.13 07:13:54.087 MODULE ( INFO ) : Received request 136203203401011-1203 > 28.02.13 07:13:54.087 PROTOCOL ( INFO ) : Received UMCP COMMAND REQUEST 136203203401011-1203 > 28.02.13 07:13:54.087 MODULE ( INFO ) : Executing ['computerroom/room/acquire'] Another time, the acquire as well as several update commands were successful. Then, an update command hanged: > ... > 28.02.13 08:38:36.558 MODULE ( INFO ) : Executing ['computerroom/update'] > 28.02.13 08:38:36.559 MODULE ( INFO ) : Update: result: {'computers': [], 'locked': False, 'user': 'uid=Administrator,cn=users,dc=deadlock51,dc=local'} > 28.02.13 08:38:36.559 PROTOCOL ( INFO ) : Sending UMCP RESPONSE 136203711648426-101 > 28.02.13 08:38:36.835 MODULE ( PROCESS ) : connection to 10.201.51.11 is dead for 10.01s - reconnecting > 28.02.13 08:47:04.518 PARSER ( INFO ) : UMCP REQUEST 136203762451050-14 parsed successfully > 28.02.13 08:47:04.518 MODULE ( INFO ) : Received request 136203762451050-14 > 28.02.13 08:47:04.518 PROTOCOL ( INFO ) : Received UMCP EXIT REQUEST 136203762451050-14 > 28.02.13 08:47:04.518 MODULE ( INFO ) : EXIT: module shutdown in 100ms > 28.02.13 08:47:04.518 PROTOCOL ( INFO ) : Sending UMCP RESPONSE 136203762451050-14 > 28.02.13 08:47:04.624 MODULE ( INFO ) : Commiting suicide > 28.02.13 08:47:04.624 MODULE ( INFO ) : Cleaning up > 28.02.13 08:47:04.625 MODULE ( INFO ) : room info: {...} > 28.02.13 08:47:04.625 MAIN ( WARN ) : Shutting down all open connections
Durch das terminate() scheint das interne Thread handling vollkommen aus dem Tritt gekommen zu sein. Daher habe ich das terminate() jetzt via patch entfernt. Der Versuch, über die Funktion shutdownAndDestroyLater() das Objekt herunterzufahren, wurde wieder zurückgenommen. Stattdessen wird in run() nach dem Verlassen der Thread-Main-Loop die Funktion deleteLater() selbständig aufgerufen. Das bedeutet, dass ab sofort nach dem Aufruf von stop() nicht mehr damit gerechnet werden kann, dass noch ein gültiges Objekt vorliegt, da QT dieses jetzt automatisch aufräumt. Neben der ItalcVncConnection wurde im Computerraummodul ebenfalls eine ITalcCoreConnection erstellt, die auf die ItalcVncConnection zurückgegriffen hat. Diese wird jetzt ebenfalls beim Reconnection entfernt. Da der Destruktor von ITalcCoreConnection die stop()-Funktion von ItalcVncConnection aufruft, darf nur die ITalcCoreConnection entfernt werden (oder wenn keine ItalcCoreConnection-Instanz vorhanden ist, auch direkt die ItalcVncConnection-Instanz). Changelogeintrag bleibt aktuell. ucs-school-umc-computerroom (3.0.7-1) unstable; urgency=low italc (2:2.0.18-1) unstable; urgency=low
OK, die iTalc Verbindungen scheinen stabil zu sein, auch "Beaufsichtigung reinitialisieren" kann aggressiv genutzt werden und führt nicht zu SegFaults. Auch häufiges Raumwechseln ist möglich.
UCS@school 3.1 R2 has been released: http://download.univention.de/doc/release-notes-ucsschool-3.1-rev2.pdf If this error occurs again, please use "Clone This Bug".