2012-01-26 10 views
5

Moje pytania są następujące:ustalić, czy funkcja jest asynchroniczny sygnał bezpieczny (można nazwać wewnątrz obsługi sygnału)

  1. Czy istnieje sposób, aby jednoznacznie określić, czy funkcja jest asynchroniczny sygnał-bezpieczny, jeśli nie masz dostępu do jego realizacji?
  2. Jeśli nie, czy istnieje sposób sprawdzenia, czy funkcja jest wystarczająco bezpieczna dla sygnału asynchronicznego, aby wywołać funkcję obsługi sygnału?

Jeśli czytasz strony podręcznika signal() lub sigaction(), otrzymujesz listę funkcji asynchronizujących sygnał (funkcje, które można bezpiecznie wywoływać wewnątrz funkcji obsługi sygnału). Uważam jednak, że ta lista nie jest wyczerpująca. Na przykład, następująca strona http://linux.die.net/man/7/signal pod asynchroniczny sygnał-safe funkcje nagłówku czytamy:

POSIX.1-2004 (znany również jako POSIX.1-2001 Technicznej Sprostowanie 2) wymaga wdrożenia do zagwarantowanie, że następujące funkcje mogą być bezpiecznie wywoływane wewnątrz obsługi sygnału:

Następnie następuje lista normalnych funkcji bezpiecznego asynchronizmu wymienionych na stronach podręcznika man powyżej. Czytając to, mówi "wymaga", a nie "są to jedyne".

Na przykład, this site mówi, że back_trace_symbols_fd() jest bezpieczny dla asynchronizmu. Ta funkcja uzyskuje dane z dladdr() i nie używa malloc() jak back_trace_symbols(), więc wygląda na to, że może być bezpieczna. Zrobiłem też kilka testów, a wyjściowa struktura dladdr() zawiera zmienne char *, ale te NIE są przestarzałe w czasie wykonywania. Łańcuch znaków, który wskazują one w czasie wykonywania, nawet przed wywołaniem dladdr().

Wszelkie przemyślenia i pomysły, które mogą wskazać mi właściwy kierunek, są mile widziane.

+2

Nie zapomnij się głosować użytecznych odpowiedzi na pytania, czy aby zaakceptować najbardziej użytecznej odpowiedzi na każde z pytań. Jeśli nie jesteś pewien, spójrz na [FAQ] (http://stackoverflow.com/faq), a zwłaszcza [Jak zadawać pytania tutaj?] (Http://stackoverflow.com/faq#howtoask) –

Odpowiedz

4

Jeśli nie masz dostępu do implementacji funkcji, możesz przejrzeć stronę podręcznika. Jeśli strona podręcznika nie mówi, że jest asynchroniczna, a standard POSIX nie mówi, że jest bezpieczny asynchronicznie, jedynym bezpiecznym wnioskiem jest "nie jest tak asynchroniczny" (w połączeniu z "nie używaj").).

Nie ma w 100% niezawodnego sposobu na sprawdzenie, czy dana funkcja jest asynchroniczna. Pamiętaj, że testowanie może pokazać tylko obecność błędów, a nie ich brak (Dijkstra). Sam fakt, że nie udaje ci się połknąć funkcji, która źle funkcjonuje podczas testu, może po prostu oznaczać, że twoje testy nie są odpowiednie (ale bądź pewien, że ważny klient, którego nie możesz sobie pozwolić na obrażenie, natychmiast i przypadkowo wymyśli niesamowicie skuteczną test demonstrujący, że funkcja nie jest tak asynchroniczna, jak tylko zwolnisz kod z błędnym założeniem).

+0

To podejście jest dość frustrujące, ponieważ na przykład 'strlen' i' memcpy' nie są gwarantowane jako bezpieczny sygnał asynchroniczny. Ale musisz po prostu z tym żyć - nigdy nie wiesz, kiedy jakaś jasna iskra wymyśli bajecznie zoptymalizowane "memcpy", które naprawdę nie jest powtórne.W każdym razie standard C mówi, że funkcje biblioteczne w ogóle nie mogą być wywołane w ogóle z procedur obsługi sygnału (asynchroniczny sygnał-niebezpieczny mówi tylko, że nie można go wywołać z programu obsługi dla sygnału, który tak właśnie zdarzył się przerwać inną niebezpieczną funkcję, ale to jest podchwytliwa rzecz, aby uzyskać jakąkolwiek przewagę). –

+0

@SteveJessop strlen() nie jest zdefiniowany jako bezpieczny sygnał asynchroniczny na stronie man w sigaction(), ale możesz zaimplementować swoją własną wersję, która jest bezpieczna dla sygnałów asynchronicznych. Wszystko, co robi, to zlicza znaki, które nie są NULL, a kiedy osiągniesz NULL, zwróć tę wartość. – Roberto

+0

@ JonathanLeffler Czy wiesz, dlaczego niektóre strony podręcznika określają bezpieczeństwo wątków i bezpieczeństwo sygnału, a inne nie? Zgaduję, że powinienem śledzić strony man mojego systemu operacyjnego. Niektóre strony podręcznika określają funkcję atrybutu (5) (nie wiem, czy jest to funkcja), która określa to wszystko i więcej. Czy wiesz, jak uzyskać dostęp do tego? Zobacz przykładową stronę man: http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?dladdr+3 – Roberto

0

Co masz nadzieję osiągnąć w obsłudze sygnału? Powinieneś rozważyć, czy jest to odpowiednie miejsce. Jest prawdopodobnie najlepiej stosować się do zaleceń strony człowieka:

In general, signal handlers should do little more 
than set a flag; most other actions are not safe. 
+1

Możesz zrobić dużo więcej w obsłudze sygnału. Musisz tylko uważać. Zobacz na przykład: http://code.google.com/p/plcrashreporter/ – Roberto