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?
Quali sono i tuoi thread bloccati? 'gdb' può dirti se sono bloccati nello spazio utente. 'ps axlm' può dirti nel campo' WCHAN'. –
È 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 –
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)' –