2012-12-26 14 views
9

Bazı arka plan:Linux uygulamasında sahte uyandırma nasıl tetiklenir?

Ben üçüncü şahıs donanım ve kapalı bir kaynak sürücüsü kullanan bir uygulama var. Sürücüde, aygıtın rastgele bir süre sonra yanıt vermeyi durdurmasına neden olan bir hata var. Bu, sürücünün içinde görünen bir çıkmazdan kaynaklanıyor ve her zaman 7/24 oldukça görünür bir ortamda bulunan, uygulamamın düzgün çalışmasını engelliyor.

Bulduğum şey, GDB'yi sürece eklemenin ve GDB'yi işlemden hemen çıkarmanın, aygıtın işlevselliğini sürdürmesiyle sonuçlandığını buldu. Bu, sürücünün kendisinde bir iplik kilitleme sorunu olduğuna dair ilk göstergemdi. Bir çıkmaz yol açan bir tür yarış durumu var. GDB'nin takılması açık bir şekilde ipliklerin yeniden şekillendirilmesine neden oluyordu ve muhtemelen onları bekleme durumundan dışarı atıyordu, bu da onların koşullarını yeniden değerlendirmelerine ve böylece çıkmazı kırmasına neden oluyordu.

soru:

sorum basitçe şudur: Onların bekleme durumu kesmek için programdaki tüm konuları tetiklemek için bir uygulama için temiz bir bekleme var mı? kesinlikle (en azından benim uygulanmasına ilişkin) çalışır bir şey başka bir işlem bir SIGCONT tarafından SIGSTOP hemen ardından göndermektir (yani bash): Bu süreç ve her şeyi içinde sahte uyandırma tetikler

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

hayata geri döner.

Sürecimdeki tüm parçacıkların sahte uyanmasını tetikleyen akıllı bir yöntem olduğunu umuyorum. pthread_cond_broadcast(...)'u düşünün, ancak beklenen gerçek koşul değişkenine erişmeden.

Bu mümkün mü ya da tek yaklaşımım olan kill gibi bir programa güveniyor mu?

+2

Konuların neler engellendi? gdb, kullanıcı alanında engellendiğini söyleyebilir. 'ps axlm'' WCHAN' alanında size söyleyebilir. –

+0

Tam olarak söyleyebilmem benim için zor - iş parçacıkları çıkmaz çifti. Pthread_cond_wait'de iki iş parçacığı vardır; Yanlış olabilirim. Bu yüzden herşeyi vurmaya çalışıyorum. Ben ps axlm'den habersizdim ve bir dahaki sefere sorunu yakaladığımda daha fazla veri toplamak için kullanacağım. Çok zor ve maalesef herhangi bir reprodüksiyon aşaması yok. Bulgularımı rapor edeceğim. –

+1

Her iş parçacığının yığınını yakalamak için bir komut dosyası kullanabilirsiniz. "gdb -ex" sayfalandırma ayarlandı 0 "-ex" iş parçacığı tüm bt'yi uygular --batch -p $ (pidof EXECUTABLE_NAME) ' –

cevap

4

Şu an yaptığınız gibi, muhtemelen en doğru ve en basit olanıdır. Çekirdeğindeki "belirli bir süreçte tüm bekleyen futexes'leri uyandırmak" yoktur, bunu daha doğrudan elde etmek için ihtiyacınız olan şey budur.

"Kilitlenme" uyandırmama hatası "pthread_cond_wait" adresinde iken, ancak kilitlenme dışı bırakılan bir sinyalle kesintiye uğrarsa, hatanın uygulamada bulunamayacağını unutmayın; Aslında pthread durum değişkenlerinin uygulanmasında olmalıdır. glibc, durum değişkenli uygulamasında düzeltilmemiş hatalar olduğunu biliyor; http://sourceware.org/bugzilla/show_bug.cgi?id=13165 ve ilgili hata raporlarına bakın. Bununla birlikte, yeni bir tane bulmuş olabilirsiniz, çünkü varolan bilinenlerin bir futex ile sinyalleri keserek bekletilebileceğini düşünmüyorum. Bu hatayı glibc hata izleyicisine bildirebilirseniz çok yardımcı olur.

+0

Bunu keşfedeceğim. Teşekkür ederim. –

+0

Şu anda David'in yukarıdaki soru hakkındaki yorumlarına dayanarak daha fazla veri topluyorum. Bu sorunun daha iyi anlaşılmasına ve bir glibc hatasının olası olup olmadığına inanıyorum. Benim soruma göre, bu cevabı birkaç gün boyunca kabul edip başka birinin herhangi bir fikri olup olmadığını görmek için elimden geleni yapacağım. Sinyalizasyon yöntemi, sadece daha iyi olabilir gibi görünüyor. Yardım ettiğin için teşekkür ederim. –