2010-06-28 2 views
14

레이스 컨디션이있는 코드가 있습니다 ... 컨디션이 일관되게 발생하지 않기 때문에 경쟁 조건이라는 것을 알고 있으며, 듀얼 코어 머신에서 자주 발생하는 것으로 보입니다 .레이스 컨디션을 찾는 방법

추적 할 때 절대로 발생하지 않습니다. 하지만 교착 상태에 빠질 가능성도 있습니다. 이것이 발생하거나 발생하지 않는 로그의 완료 단계를 분석함으로써이 버그를 단일 기능으로 찾아 낼 수있었습니다. 그러나, 나는 함수의 범위에서 이것이 어디에서 일어나고 있는지 모른다. 최상위 수준이 아닙니다.

로그 명령문이나 중단 점을 추가하면 경쟁 조건 인 경우 타이밍이 변경되어이 문제가 발생하지 않습니다.

어디에서 이것이 일어나고 있는지 정확히 알려주는 경쟁 조건 분석기를 얻는 데 사용할 수있는 기법이 있습니까?

이것은 Visual Studio 9에서 C++ (비 관리 형)입니다.

+0

마지막으로, 나는 로컬 알고 :

당신은

이 예제 -fsanitize=thread 플래그를 사용하여 코드를 컴파일 . 나는 그것을 "구식 방식"으로하고 콜링 트리를 그래프로 작성하고 손으로 각 통화의 잠금 시간을 강조 표시했습니다. 필자의 경우 2 개의 소스 파일과 소수의 기능으로 이전되었지만 매우 귀중한 것으로 입증되었습니다. –

답변

4

코드의 여러 부분에서 잠든다. 스레드 세이프 인 것은 (심지어 비동기 코드 인 경우에도) 초 단위로 대기 상태가 되더라도 스레드 세이프가됩니다.

2

실제로 경쟁 조건을 자동으로 찾는 몇 가지 시도가 있습니다.

  • Happens-Before Race Detection
  • Hybrid Race Detection
  • Lockset-Based Race Checker
    • 내가 경쟁 조건 감지와 함께 읽는 또 다른 용어는 RaceFuzzer,하지만 난 그것에 대해 정말 유용한 정보를 찾을 수 없습니다.

      나는이 주제에 관한 이론적 논문이 있기 때문에 이것이 상대적으로 잘 조사 된 분야라고 생각한다. 그러나 위의 키워드 중 하나를 검색해보십시오. 어쩌면 유용한 정보를 찾을 수 있습니다.

    3

    이러한 문제를 추적하는 가장 좋은 방법은 Visual Studio에서 CHESS을 사용하는 것입니다. 이것은 사용하기 쉬운 도구는 아니며 아마도 앱의 하위 섹션을 점진적으로 테스트해야 할 것입니다. 행운을 빕니다.

    0

    코드 게시를 시도해 볼 수 있습니다. 인텔은 시도 할 수있는 다양한 병렬 도구도 제공합니다.

    2

    저는 경주 조건을 찾기 위해 Visual Studio의 추적 포인트를 사용하는 데 약간의 행운이있었습니다. 물론 그것은 여전히 ​​타이밍에 영향을 미치지 만, 적어도 사용했을 경우 경쟁 조건이 완전히 발생하는 것을 방지하기에는 충분하지 않았습니다. 적어도 전용 로그보다 덜 파괴적이었던 것 같습니다.

    그 외에도 다른 사람들이 살펴볼 수 있도록 코드를 게시 해보십시오. 코드를 자세하게 연구하는 것은 경쟁 조건을 찾는 나쁜 방법이 아닙니다.

    +0

    +1 코드 리뷰 용. 코드 리뷰는 항상 좋은 일입니다! –

    1

    보호되지 않은 리소스 일 수도 있습니다. 일관성없는 동작을 설명 할 수 있습니다 (특히 단일 코어에서 제대로 작동하고 이중 코어가 아닌 경우). 어떤 경우 든 코드 검토 (경쟁 조건 및 스레드로부터 안전하지 않은 소스 코드 모두)가 솔루션에 대한 최단 경로가 될 수 있습니다.

    2

    그래서 나를위한 슬레지 해머 방법은 다음과 같이 많은 인내가 필요하며 최선의 시나리오에서는 올바른 방향으로 이동할 수 있습니다.이 문제를 해결하기 위해이 방법을 사용했습니다. 필자는 추적 점을 사용하고 있는데, 하나는 추적 대상이 될 것으로 예상되는 상위 수준 함수의 시작 부분과 끝 지점에 하나씩 사용되었습니다. 추적 점을 아래로 이동하십시오. 함수 시작 부분에 추적 점을 추가하면 버그가 발생하지 않게되고, 다시 조건을 재현 할 때까지 추적 점을 아래로 이동하십시오. 그 아이디어는 결국 안전하지 않은 코드를 유발하는 호출 후에 트레이스 포인트가 타이밍에 영향을 미치지 않는다는 것입니다. 또한 출력 창에 유의하십시오. 당신의 버그는 어떤 메시지들 사이에서 발생합니까? 추적 점을 사용하여이 범위를 줄일 수도 있습니다.

    관리 가능한 코드 영역으로 버그를 좁히면 중단 점을 넣을 수 있고이 시점에서 다른 스레드가 무엇인지 확인할 수 있습니다.

    1

    특정 유형의 경쟁 조건을 확인할 수있는 Intel Inspector과 같은 도구를 사용할 수 있습니다.

    5

    ThreadSanitizer이라고하는 CLang 및 gcc 4.8 이상에 포함 된 도구가 있습니다. 이 발생했다 어디 심각한 경쟁 조건을했다

    $ 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