Bug 27534 - SegFault des Modulprozess beim Reinitialisieren
SegFault des Modulprozess beim Reinitialisieren
Status: CLOSED FIXED
Product: UCS@school
Classification: Unclassified
Component: UMC - Computer room
UCS@school 3.0
Other Linux
: P5 normal (vote)
: UCS@school 3.1 R2
Assigned To: Sönke Schwardt-Krummrich
Florian Best
: interim-1
: 31213 (view as bug list)
Depends on:
Blocks: 31036
  Show dependency treegraph
 
Reported: 2012-06-11 17:00 CEST by Andreas Büsching
Modified: 2016-01-25 15:05 CET (History)
4 users (show)

See Also:
What kind of report is it?: ---
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments
Might help a little (1.78 KB, patch)
2012-06-12 10:47 CEST, Andreas Büsching
Details | Diff
Testskript für regelmäßigen Raumwechsel (1.19 KB, text/plain)
2013-04-04 18:05 CEST, Sönke Schwardt-Krummrich
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Büsching univentionstaff 2012-06-11 17:00:28 CEST
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
Comment 1 Andreas Büsching univentionstaff 2012-06-12 10:30:58 CEST
Ich habe dazu einen iTALC-Bug angelegt:

https://sourceforge.net/tracker/?func=detail&aid=3534527&group_id=132465&atid=724375
Comment 2 Andreas Büsching univentionstaff 2012-06-12 10:47:09 CEST
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.
Comment 3 Sönke Schwardt-Krummrich univentionstaff 2013-03-25 17:25:12 CET
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)
Comment 4 Sönke Schwardt-Krummrich univentionstaff 2013-04-04 18:03:39 CEST
(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.
Comment 5 Sönke Schwardt-Krummrich univentionstaff 2013-04-04 18:05:56 CEST
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
Comment 6 Sönke Schwardt-Krummrich univentionstaff 2013-04-11 18:08:51 CEST
Changelog-Eintrag wurde erstellt.
Comment 7 Florian Best univentionstaff 2013-04-24 15:36:36 CEST
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.
Comment 8 Alexander Kläser univentionstaff 2013-05-03 15:32:14 CEST
*** Bug 31213 has been marked as a duplicate of this bug. ***
Comment 9 Alexander Kläser univentionstaff 2013-05-24 15:10:26 CEST
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
Comment 10 Sönke Schwardt-Krummrich univentionstaff 2013-05-27 16:28:11 CEST
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
Comment 11 Florian Best univentionstaff 2013-05-30 10:59:08 CEST
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.
Comment 12 Sönke Schwardt-Krummrich univentionstaff 2013-06-07 21:39:38 CEST
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".