2012-12-26 3 views
9

Einige Hintergrundinformationen:Wie löst man ein ungewolltes Aufwecken in einer Linux-Anwendung aus?

Ich habe eine Anwendung, die auf externe Hardware und einen Closed-Source-Treiber angewiesen ist. Der Treiber enthält derzeit einen Fehler, der dazu führt, dass das Gerät nach einer zufälligen Zeit nicht mehr reagiert. Dies wird durch einen offensichtlichen Stillstand im Treiber verursacht und unterbricht die ordnungsgemäße Funktion meiner Anwendung, die sich in einer ständig sichtbaren und rund um die Uhr sichtbaren Umgebung befindet.

Was ich gefunden habe, ist, dass die Verbindung von GDB mit dem Prozess und das sofortige Loslösen von GDB aus dem Prozess in der Wiederaufnahme der Funktionalität des Geräts resultiert. Dies war mein erster Hinweis darauf, dass es innerhalb des Treibers ein Threads Locking-Problem gab. Es gibt eine Art von Race Condition, die zu einem Stillstand führt. Das Anhängen von GDB führte offensichtlich dazu, dass Threads neu gemischt und wahrscheinlich aus ihrem Wartezustand herausgeschoben wurden, was dazu führte, dass sie ihre Bedingungen neu bewerteten und damit den Deadlock lösten.

Die Frage:

Meine Frage ist einfach: Gibt es eine saubere Wartezeit für eine Anwendung alle Themen innerhalb des Programms auslösen ihre Wartezustand zu unterbrechen? Eine Sache, die auf jeden Fall funktioniert (zumindest auf meiner Implementierung) ist ein SIGSTOP zu senden, unmittelbar gefolgt von einem SIGCONT aus einem anderen Prozess (dh von bash):

kill -19 `cat /var/run/mypidfile` ; kill -18 `cat /var/run/mypidfile` 

Dies löst eine unechte Weck- innerhalb des Prozesses und alles kommt zurück ins Leben.

Ich hoffe, dass es eine intelligente Methode gibt, um ein ungewolltes Aufwecken aller Threads in meinem Prozess auszulösen. Denken Sie pthread_cond_broadcast(...), aber ohne Zugriff auf die aktuelle Zustandsvariable, auf die gewartet wird.

Ist dies möglich, oder ist ein Programm wie kill mein einziger Ansatz?

+2

Worauf sind Ihre Threads blockiert? 'gdb' kann Ihnen sagen, ob sie im Benutzerbereich blockiert sind. 'ps axlm' kann Ihnen im' WCHAN' Feld sagen. –

+0

Es ist schwierig für mich, genau zu sagen, welche Threads das festgefahrene Paar sind. Es gibt zwei Threads in 'pthread_cond_wait', die meine beste Schätzung als die anstößigen Threads sind. Ich könnte falsch sein. Das ist der Grund, warum ich versuche, jeden Thread zu treffen. Ich wusste nichts von "ps axlm" und werde damit beim nächsten Mal mehr Daten sammeln. Es ist sehr schwer fassbar und es gibt leider keine Reproduktionsschritte. Ich werde meine Ergebnisse melden. –

+1

Sie können ein Skript verwenden, um den Stapel jedes Threads abzufangen. 'gdb -ex" setze Paginierung 0 "-ex" thread apply all bt "--batch -p $ (pidof EXECUTABLE_NAME)' –

Antwort

4

Die Art, wie Sie es gerade tun, ist wahrscheinlich die korrekteste und einfachste. Es gibt keine "wake alle wartende futexes in einem bestimmten Prozess" -Operation im Kernel, die Sie benötigen, um dies direkter zu erreichen.

Beachten Sie, dass der Fehler nicht in der Anwendung sein kann, wenn der "Deadlock" in pthread_cond_wait ist, aber die Unterbrechung mit einem Signal aus dem Deadlock ausbricht; es muss tatsächlich in der Implementierung von Pthread-Zustandsvariablen sein. glibc hat in seiner Zustandsvariablen-Implementierung nicht behobene Fehler bekannt; siehe http://sourceware.org/bugzilla/show_bug.cgi?id=13165 und zugehörige Fehlerberichte. Vielleicht haben Sie aber eine neue gefunden, da ich nicht glaube, dass die bestehenden bekannten durch Ausbrechen der Futex mit einem Signal behoben werden können. Wenn Sie diesen Bug dem glibc bug tracker melden können, wäre das sehr hilfreich.

+0

Ich werde das erkunden. Vielen Dank. –

+0

Ich sammle derzeit mehr Daten basierend auf Davids Kommentaren zu der obigen Frage. Ich glaube, das wird mir helfen, das Problem besser zu verstehen und ob ein Glibc-Bug eine Möglichkeit ist. Was meine Frage betrifft, werde ich diese Antwort ein paar Tage lang ablehnen, um zu sehen, ob jemand andere Ideen hat. Die Signalisierungsmethode WORKS, es scheint nur, als könnte es besser sein. Danke für Ihre Hilfe. –