2012-12-26 5 views
9

Alcuni retroscena:Come attivare il wake-up spurio in un'applicazione Linux?

Ho un'applicazione che si basa su hardware di terze parti e un driver closed source. Al momento il driver presenta un bug che impedisce al dispositivo di rispondere dopo un periodo di tempo casuale. Ciò è causato da un apparente deadlock all'interno del driver e interrompe il corretto funzionamento della mia applicazione, che si trova in un ambiente sempre visibile 24/7 ad alta visibilità.

Quello che ho trovato è che allegando GDB al processo, e immediatamente staccando GDB dal processo si ottiene la funzionalità di riattivazione del dispositivo. Questa è stata la mia prima indicazione che c'era un problema di blocco dei thread all'interno del driver stesso. C'è una sorta di condizione di competizione che porta a un punto morto. Allegare GDB stava ovviamente causando un rimpasto di thread e probabilmente spingendoli fuori dal loro stato di attesa, inducendoli a rivalutare le loro condizioni e quindi a rompere lo stallo.

La domanda:

La mia domanda è semplicemente questa: c'è un'attesa pulita per un'applicazione per attivare tutte le discussioni all'interno del programma di interrompere il loro stato di attesa? Una cosa che sicuramente funziona (almeno sul mio implementazione) è quello di inviare un SIGSTOP seguito immediatamente da un SIGCONT da un altro processo (cioè da bash):

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

Questo innesca una sveglia spurio all'interno del processo e tutto torna in vita.

Spero che esista un metodo intelligente per attivare una scia spuria di tutti i thread all'interno del mio processo. Pensa a pthread_cond_broadcast(...) ma senza avere accesso alla variabile di condizione attuale in attesa.

È possibile o si basa su un programma come kill il mio unico approccio?

+2

Quali sono i tuoi thread bloccati? 'gdb' può dirti se sono bloccati nello spazio utente. 'ps axlm' può dirti nel campo' WCHAN'. –

+0

È difficile per me dire esattamente -questi- i thread sono la coppia bloccata. Ci sono due thread in 'pthread_cond_wait' che sono la mia ipotesi migliore come thread offensivi. Potrei essere sbagliato. Questo è il motivo per cui sto tentando di colpire -every- thread. Non ero a conoscenza di 'ps axlm' e lo userò per raccogliere più dati la prossima volta che rileverò il problema. È altamente sfuggente e purtroppo non ci sono passaggi di riproduzione. Riferirò i miei risultati –

+1

Puoi usare uno script per catturare lo stack di ogni thread. 'gdb -ex" imposta impaginazione 0 "-ex" thread applica tutto bt "--batch -p $ (pidof EXECUTABLE_NAME)' –

risposta

4

Il modo in cui lo stai facendo in questo momento è probabilmente il più corretto e più semplice. Non vi è alcuna operazione di "svegliando tutti i futures in attesa in un dato processo" nel kernel, che è ciò che sarebbe necessario per ottenere questo risultato più direttamente.

Si noti che se il deadlock "guasto a riattivazione" è in pthread_cond_wait ma interrompendolo con un segnale interrotto dal deadlock, il bug non può essere nell'applicazione; deve essere effettivamente nell'implementazione delle variabili di condizione pthread. glibc ha noti bug non risolti nella sua implementazione della variabile condition; vedi http://sourceware.org/bugzilla/show_bug.cgi?id=13165 e segnalazioni di bug correlate. Tuttavia, potresti averne trovato uno nuovo, dal momento che non penso che i conosciuti esistenti possano essere risolti rompendo fuori dal futex l'attesa con un segnale. Se puoi segnalare questo bug al bug tracker di glibc, sarebbe molto utile.

+0

Esplorerò questo. Grazie. –

+0

Attualmente sto raccogliendo più dati sulla base dei commenti di David sulla domanda di cui sopra. Credo che questo mi aiuterà a capire meglio il problema e se un bug di glibc è una possibilità. Per quanto riguarda la mia domanda, non tarderò ad accettare questa risposta per un paio di giorni per vedere se qualcun altro ha qualche idea. Il metodo di segnalazione FUNZIONA, sembra proprio che potrebbe essere migliore. Grazie per l'aiuto. –

Problemi correlati