2010-06-28 16 views
14

Ho un po 'di codice con una condizione di gara in esso ... So che si tratta di una condizione di competizione perché non accade in modo coerente e sembra accadere più spesso su macchine dual core .Modi per trovare una condizione di gara

Non succede mai quando sto tracciando. Anche se, c'è la possibilità che potrebbe essere un deadlock pure. Analizzando le fasi di completamento dei log in cui ciò avviene e non si verifica, sono stato in grado di individuare questo bug in una singola funzione. Tuttavia, non so dove sta accadendo la portata della funzione. Non è al massimo livello.

L'aggiunta di istruzioni di registro o punti di interruzione modifica i tempi se si tratta di una condizione di competizione e impedisce che ciò accada.

C'è qualche tecnica che posso utilizzare oltre a ottenere un analizzatore di condizioni di gara che mi consenta di individuare dove sta accadendo?

Questo è in Visual Studio 9, con C++ (della varietà non gestita).

+0

L'ultima volta che ho avuto un grave condizione di gara, sapevo a livello locale dove stava avvenendo . L'ho fatto alla "vecchia maniera" e ho fatto ricorso alla rappresentazione grafica degli alberi di chiamata e all'evidenziazione delle durate dei blocchi per ogni chiamata a mano. Nel mio caso è stato relegato a 2 file sorgente e una manciata di funzioni, ma si è rivelato inestimabile. –

risposta

4

Mettere il sonno in varie parti del codice. Qualcosa che è a prova di threads sarà thread-sicuro anche se (o codice asincrono) dorme per anche secondi.

2

Effettivamente ci sono alcuni tentativi di trovare le condizioni di gara automaticamente.

Un altro termine che ho letto in combinazione con race condition rilevazione è RaceFuzzer, ma non ero in grado di trovare le informazioni realmente utili al riguardo.

Penso che questo sia un campo di indagine relativamente ad arco, quindi ci sono, per quanto ne so, documenti principalmente teorici su questo argomento. Tuttavia, prova a cercare su google una delle parole chiave sopra, forse troverai alcune informazioni utili.

3

Il modo migliore che conosco per rintracciare questi giù è quello di utilizzare CHESS in Visual Studio. Questo non è uno strumento semplice da utilizzare e probabilmente richiederà la verifica di sottosezioni della tua app in modo progressivo. In bocca al lupo.

0

Potrebbe provare a postare il codice. Intel offre anche vari strumenti paralleli da provare.

2

Ho avuto un po 'di fortuna nell'usare i tracepoint di Visual Studio per trovare condizioni di gara. Ovviamente influenza ancora i tempi, ma nei casi in cui l'ho usato, almeno, non è stato sufficiente a impedire completamente che si verifichino le condizioni della gara. Sembrava meno dirompente del logging dedicato, almeno.

Oltre a questo, provare a postare il codice consentendo ad altri di guardarci sopra. Basta studiare il codice in dettaglio non è un brutto modo per trovare le condizioni di gara.

+0

+1 per le revisioni del codice. Le recensioni del codice sono sempre una buona cosa !. –

1

Può anche essere una risorsa non protetta, che può spiegare comportamenti non coerenti (specialmente se su un singolo core funziona bene e non su dual core). In ogni caso, la revisione del codice (per entrambe le condizioni di gara e il codice sorgente non thread-safe) può essere il percorso più breve per la soluzione.

2

Quindi, il metodo a mazza per me è stato il seguente, che richiede molta pazienza e può nel migliore dei casi portarti sulla buona strada.L'ho usato per capire cosa stava succedendo con questo particolare problema. Ho utilizzato i tracepoint, uno all'inizio della sospetta funzione di alto livello e uno alla fine. Sposta il tracepoint verso il basso. Se l'aggiunta del punto di tracciamento all'inizio della funzione fa sì che il bug non si verifichi più, spostare il punto di traccia verso il basso fino a quando non è possibile riprodurre nuovamente la condizione. L'idea è che il tracepoint non inciderà sui tempi se lo metti dopo la chiamata che alla fine attiva codice non sicuro, ma lo farà se lo metti prima. Inoltre, prendi nota della finestra di output. Tra quali messaggi si verifica il tuo bug? È possibile utilizzare tracepoint per restringere anche questo intervallo.

Una volta ristretto il bug in una regione di codice gestibile, è possibile inserire punti di interruzione e dare un'occhiata a ciò che gli altri thread sono in grado di raggiungere.

1

È possibile utilizzare strumenti come Intel Inspector che sono in grado di verificare determinati tipi di condizioni di gara.

5

C'è uno strumento incluso in CLang e gcc 4.8+ chiamato ThreadSanitizer.

Si compila il codice utilizzando il flag -fsanitize=thread

Esempio:

$ cat simple_race.cc 
#include <pthread.h> 
#include <stdio.h> 

int Global; 

void *Thread1(void *x) { 
    Global++; 
    return NULL; 
} 

void *Thread2(void *x) { 
    Global--; 
    return NULL; 
} 

int main() { 
    pthread_t t[2]; 
    pthread_create(&t[0], NULL, Thread1, NULL); 
    pthread_create(&t[1], NULL, Thread2, NULL); 
    pthread_join(t[0], NULL); 
    pthread_join(t[1], NULL); 
} 

E l'uscita

$ clang++ simple_race.cc -fsanitize=thread -fPIE -pie -g 
$ ./a.out 
================== 
WARNING: ThreadSanitizer: data race (pid=26327) 
    Write of size 4 at 0x7f89554701d0 by thread T1: 
    #0 Thread1(void*) simple_race.cc:8 (exe+0x000000006e66) 

    Previous write of size 4 at 0x7f89554701d0 by thread T2: 
    #0 Thread2(void*) simple_race.cc:13 (exe+0x000000006ed6) 

    Thread T1 (tid=26328, running) created at: 
    #0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b) 
    #1 main simple_race.cc:19 (exe+0x000000006f39) 

    Thread T2 (tid=26329, running) created at: 
    #0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b) 
    #1 main simple_race.cc:20 (exe+0x000000006f63) 
================== 
ThreadSanitizer: reported 1 warnings 
Problemi correlati