2012-12-26 6 views
9

Niektóre tła:Jak wyzwalać fałszywe budzenie w aplikacji systemu Linux?

mam aplikację, która opiera się na sprzęcie firm trzecich i kierowca źródłowego zamkniętym. Sterownik ma obecnie błąd, który powoduje, że urządzenie przestaje odpowiadać po losowym czasie. Jest to spowodowane widocznym zakleszczeniem w sterowniku i przerywa prawidłowe funkcjonowanie mojej aplikacji, która jest zawsze w dobrze widocznym środowisku 24/7.

To, co odkryłem, to dołączenie GDB do procesu i natychmiastowe odłączenie GDB od procesu powoduje wznowienie działania urządzenia. To był mój pierwszy dowód, że w samym sterowniku wystąpił problem z blokowaniem wątków. Jest jakiś rodzaj wyścigu, który prowadzi do impasu. Dołączenie GDB oczywiście spowodowało pewne przetasowanie wątków i prawdopodobnie wypchnięcie ich z ich stanu oczekiwania, powodując ich ponowną ocenę ich warunków i tym samym przerwanie impasu.

Pytanie:

Moje pytanie jest po prostu tak: jest tam czyste czekać na wniosek wyzwolić wszystkie wątki w programie przerwania ich stan oczekiwania? Jedną rzeczą, która na pewno działa (przynajmniej na moim realizacji) jest wysłać SIGSTOP następuje natychmiast przez SIGCONT od innego procesu (tj od bash):

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

To wywołuje fałszywy wake-up w ramach procesu i wszystko wraca do życia.

Mam nadzieję, że istnieje inteligentna metoda wyzwalania fałszywego przebudzenia wszystkich wątków w ramach mojego procesu. Pomyśl pthread_cond_broadcast(...), ale bez dostępu do aktualnej zmiennej warunkowej, na którą czekano.

Czy to możliwe, czy opiera się na programie takim jak: kill moje jedyne podejście?

+2

Jakie są twoje wątki zablokowane? 'gdb' może ci powiedzieć, czy są zablokowane w przestrzeni użytkownika. 'ps axlm' może Ci powiedzieć w polu' WCHAN'. –

+0

Trudno mi powiedzieć dokładnie, w którym - wątki są zakleszczoną parą. Istnieją dwa wątki w 'pthread_cond_wait', które są moim zdaniem najbardziej trafne jako obraźliwe wątki. Mogę być niepoprawny. Właśnie dlatego staram się trafić w "cały wątek". Nie wiedziałem o "ps axlm" i wykorzystam to do zebrania kolejnych danych następnym razem, gdy złapię problem. Jest to bardzo nieuchwytne i niestety nie ma żadnych etapów reprodukcji. Zgłoszę moje wnioski. –

+1

Możesz użyć skryptu, aby złapać stos każdego wątku. 'gdb -ex" ustaw paginię 0 "-ex" wątek stosuje wszystkie bt "--batch -p $ (pidof EXECUTABLE_NAME)' –

Odpowiedz

4

Sposób, w jaki to robisz, jest prawdopodobnie najbardziej poprawny i najprostszy. W jądrze nie ma żadnej "wake'owania wszystkich czekających futexów w danej operacji", co jest tym, czego potrzebujesz, aby osiągnąć to bardziej bezpośrednio.

Należy zauważyć, że jeśli nieudany "impas" jest w pthread_cond_wait, ale przerwanie go z sygnałem wyrwa się z zakleszczenia, błąd nie może być w aplikacji; musi to być rzeczywiście implementacja zmiennych warunkowych pthread. glibc zna nieusunięte błędy w swojej implementacji zmiennych warunkowych; zobacz http://sourceware.org/bugzilla/show_bug.cgi?id=13165 i pokrewne raporty o błędach. Mogłeś jednak znaleźć nowy, ponieważ nie wydaje mi się, aby istniejące znane można było naprawić przez wyjście z futex z sygnałem. Jeśli możesz zgłosić ten błąd do śledzenia błędów glibc, byłoby to bardzo pomocne.

+0

Zbadam to. Dziękuję Ci. –

+0

Obecnie zbieram więcej danych na podstawie komentarzy Davida na powyższe pytanie. Wierzę, że to pomoże mi lepiej zrozumieć problem i czy błąd w glibc jest możliwy. Jeśli chodzi o moje pytanie, wstrzymam się z zaakceptowaniem tej odpowiedzi przez kilka dni, aby sprawdzić, czy ktoś jeszcze ma jakieś pomysły. Metoda sygnalizacji DZIAŁA, wydaje się po prostu, że może być lepiej. Dzięki za pomoc. –

Powiązane problemy