2012-01-26 10 views
5

Le mie domande sono:Determinare se una funzione è async-signal-safe (può essere chiamato all'interno di un gestore di segnale)

  1. c'è un modo per stabilire in modo definitivo se una funzione è async-signal-safe se si non hai accesso alla sua implementazione?
  2. In caso contrario, c'è un modo per testare se la funzione sarebbe sufficientemente sicura per il segnale asincrono da chiamare da un gestore di segnale?

Se si legge la pagine man di segnale() o sigaction(), si ottiene una lista di funzioni async-signal-safe (funzioni che possono essere chiamate in modo sicuro all'interno di un gestore di segnale). Tuttavia, ritengo che questa lista non sia esaustiva. Ad esempio, la pagina seguente http://linux.die.net/man/7/signal, sotto le funzioni Async-segnale-safe intestazione, si legge:

POSIX.1-2004 (noto anche come POSIX.1-2001 rettifica tecnica 2) richiede un'attuazione garantire che le seguenti funzioni possano essere tranquillamente richiamate all'interno di un gestore di segnale:

E quindi procede ad elencare le normali funzioni di sicurezza del segnale asincrono elencate nelle pagine di manuale sopra. Mentre lo leggo, dice "richiede", non "questi sono gli unici".

Ad esempio, this site dice che back_trace_symbols_fd() è sicuro per segnale asincrono. Questa funzione ottiene i dati da dladdr() e non usa malloc() come back_trace_symbols(), quindi sembra che sia sicuro. Inoltre, ho fatto alcuni test e la struttura di output di dladdr() contiene le variabili char *, ma queste non sono mallocizzate in fase di runtime. La stringa di caratteri a cui puntano esiste in fase di esecuzione ancor prima che venga chiamato dladdr().

Ogni pensiero o idea che possa indirizzarmi nella giusta direzione è apprezzato.

+2

Non dimenticare di votare le risposte utili alle tue domande o di accettare la risposta più utile a ciascuna delle tue domande. Se non sei sicuro, guarda [FAQ] (http://stackoverflow.com/faq) e soprattutto [Come faccio a porre domande qui?] (Http://stackoverflow.com/faq#howtoask) –

risposta

4

Se non si ha accesso all'implementazione della funzione, è possibile consultare la pagina di manuale. Se la pagina man non dice che è async-safe, e lo standard POSIX non dice che è async-safe, l'unica conclusione sicura è "non è async-safe" (accoppiato con "do not use it")).

Non esiste un metodo affidabile al 100% per verificare se una funzione è async-safe. Ricorda, il test può mostrare solo la presenza di bug, non la loro assenza (Dijkstra). Il semplice fatto che tu non riesca a solleticare la funzione in comportamenti anomali durante il test potrebbe semplicemente significare che il tuo test non è adeguato (ma stai tranquillo, il cliente importante che non puoi permetterti di offendere immediatamente e accidentalmente escogiterà un effetto devastante test che dimostra che la funzione non è asincrona quasi quando si rilascia il codice con l'assunzione errata).

+0

Questo l'approccio è piuttosto frustrante, poiché ad esempio 'strlen' e' memcpy' non sono garantiti come sicuri dal segnale asincrono. Ma devi solo conviverci - non si sa mai quando una scintilla brillante inventerà una memcpy favolosamente ottimizzata che non è veramente un rientro.Ad ogni modo lo standard C dice che le funzioni di libreria in generale non possono essere chiamate da gestori di segnale (il segnale asincrono non sicuro dice semplicemente che non può essere chiamato da un gestore per un segnale che è appena accaduto per interrompere un'altra funzione non sicura, ma quella è una cosa complicata da cui trarre effettivamente vantaggio). –

+0

@SteveJessop strlen() non è definito come async-signal-safe nella pagina man di sigaction(), ma è possibile implementare la propria versione di esso che è async-signal-safe. Tutto ciò che fa è contare i caratteri non NULL e quando raggiungi NULL restituisci quel valore. – Roberto

+0

@ JonathanLeffler Sapete perché alcune pagine man specificano la sicurezza del thread e la sicurezza del segnale mentre altre no? Immagino che dovrei seguire le pagine man del mio sistema operativo. Alcune pagine man specificano una funzione attributes (5) (non è sicuro se si tratta di una funzione) che specifica tutto questo e altro. Sai come accedervi? Vedi Esempio di pagina man: http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?dladdr+3 – Roberto

0

Cosa speri di ottenere nel gestore del segnale? Dovresti considerare se è il posto giusto per questo. Probabilmente è meglio seguire il consiglio della pagina man:

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

Puoi fare molto di più all'interno di un gestore di segnali. Devi solo stare attento. Guarda questo ad esempio: http://code.google.com/p/plcrashreporter/ – Roberto

Problemi correlati