2010-06-28 6 views
14

У меня есть немного кода с состоянием гонки в нем ... Я знаю, что это состояние гонки, потому что это происходит не последовательно, и, похоже, это происходит чаще на двухъядерных машинах ,Способы поиска состояния гонки

Это не происходит, когда я отслеживаю. Хотя, есть вероятность, что это может быть и тупик. Анализируя этапы завершения журналов, где это происходит и не происходит, я смог точно определить эту ошибку для одной функции. Однако я не знаю, где в рамках функции это происходит. Это не на высшем уровне.

Добавление операторов журнала или контрольных точек будет менять время, если это условие гонки, и предотвратить это.

Есть ли какой-либо метод, который я могу использовать, помимо получения анализатора состояния гонки, который позволит мне точно определить, где это происходит?

Это в визуальной студии 9, с C++ (неуправляемого сорта).

+0

Последний раз я имел серьезное состояние гонки, я знал, что на месте, где оно происходило , Я сделал это «старомодным способом» и прибегнул к графическим деревьям вызова и выделил длительность блокировки для каждого вызова вручную. В моем случае это было отнесено к 2 исходным файлам и нескольким функциям, но это оказалось бесценным. –

ответ

4

Положить спит в различные части вашего кода. То, что является потокобезопасным, будет потокобезопасным, даже если он (или асинхронный код) будет спать даже на секунды.

2

Действительно, есть некоторые попытки автоматически найти условия гонки.

Другой термин, который я прочитал в сочетании с обнаружением гонки условием является RaceFuzzer, но я не смог найти действительно полезную информацию об этом.

Я думаю, что это относительно ваше поле исследований, так что, насколько я знаю, в основном теоретические работы по этому вопросу. Тем не менее, попробуйте использовать один из указанных выше ключевых слов, возможно, вы найдете полезную информацию.

3

Лучший способ узнать, как это отслеживать, - использовать CHESS в Visual Studio. Это не простой инструмент для использования, и, вероятно, потребуется постепенное тестирование подразделов вашего приложения. Удачи.

0

Можете попробовать разместить код. Intel также предлагает различные параллельные инструменты, которые вы могли бы попробовать.

2

Мне посчастливилось использовать контрольные точки Visual Studio, чтобы найти условия гонки. Конечно, это по-прежнему влияет на время, но в тех случаях, когда я его использовал, по крайней мере, этого было недостаточно, чтобы полностью предотвратить условия гонки. По крайней мере, это казалось менее разрушительным, чем посвященный каротаж.

Кроме этого, попробуйте опубликовать код, позволяющий другим просматривать его. Просто изучить код в деталях - неплохой способ найти условия гонки.

+0

+1 Для просмотра кода. Обзор кода - это всегда хорошая вещь !. –

1

Это может быть ресурс, который не защищен, что может объяснить непоследовательное поведение (особенно если на одном ядре он работает нормально, а не на двухъядерном процессоре). В любом случае, обзор кода (как для условий гонки, так и для небезопасного исходного кода) может быть кратчайшим путем к решению.

2

Итак, метод кувалды для меня был следующим, что требует много терпения и может в лучшем случае получить вас на правильном пути.Я использовал это, чтобы выяснить, что происходит с этой конкретной проблемой. Я использовал контрольные точки, один в начале предполагаемой функции высокого уровня и один в конце. Переместите точку следа вниз. Если добавление точки трассировки в начале функции приводит к тому, что ваша ошибка прекращается, переместите трассировку вниз, пока вы не сможете воспроизвести условие снова. Идея заключается в том, что трассировка не повлияет на синхронизацию, если вы поместите ее после вызова, который в конечном итоге вызывает небезопасный код, но если вы поместите его раньше. Также обратите внимание на окно вывода. Между сообщениями возникает ваша ошибка? Вы можете использовать точки трассировки, чтобы сузить этот диапазон.

Как только вы сократите свою ошибку до управляемой области кода, вы можете бросить точки останова и посмотреть, что на самом деле есть в других потоках.

1

Вы можете использовать такие инструменты, как Intel Inspector, которые могут проверять определенные типы условий гонки.

5

Существует инструмент, входящий в состав CLang и gcc 4.8+, называемый ThreadSanitizer.

Вы скомпилировать код, используя -fsanitize=thread флаг

Пример:

$ 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); 
} 

И выход

$ 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 
Смежные вопросы