2010-06-28 79 views
14

我有一些代碼與它的競爭條件......我知道這是一個競爭條件,因爲它不會一直髮生,而且它似乎更經常發生在雙核心機器上。尋找競爭條件的方法

當我追蹤時,它從不發生。儘管它也有可能陷入僵局。通過分析日誌的完成階段,我已經能夠將這個錯誤指向一個函數。但是,我不知道在這個功能範圍內發生了什麼。這不是最高級別。

添加日誌語句或斷點會改變計時,如果它是競態條件,並防止發生這種情況。

是否有任何技術可以用於獲取競速狀態分析器,以便我可以確定發生這種情況的位置?

這是在visual studio 9中,用C++(非託管品種)。

+0

上次我得了嚴重的競爭狀態,我在本地就知道它正在發生。我做了「老式的方式」,並用手繪製呼叫樹併爲每個呼叫突出顯示鎖定持續時間。在我的情況下,它被降級到2個源文件和一些函數,但它被證明是非常寶貴的。 – 2010-06-29 01:13:29

回答

4

讓你睡在代碼的不同部分。即使它(或異步代碼)偶爾幾秒鐘睡覺,線程安全的東西也會是線程安全的。

2

確實有一些嘗試自動找到競賽條件。

另一個術語我在比賽中狀態檢測一起閱讀是RaceFuzzer,但我沒能找到它真正有用的信息。

我認爲這是一個相對應的調查領域,所以有 - 據我所知 - 主要是關於這個問題的理論論文。不過,嘗試使用上面的關鍵字搜索一下,也許你會發現一些有用的信息。

3

我知道跟蹤這些的最好方法是在Visual Studio中使用CHESS。這不是一個簡單的工具,而且可能需要逐步測試應用程序的子部分。祝你好運。

0

可以嘗試發佈代碼。英特爾還提供了各種可以嘗試的並行工具。

2

我已經有了使用Visual Studio的跟蹤點找到競爭條件的運氣。當然,它仍然影響着時機,但在我使用它的情況下,至少,這還不足以完全防止競爭狀況的發生。至少,它看起來不像專用日誌那麼具有破壞性。

除此之外,請嘗試發佈允許他人查看的代碼。只是詳細研究代碼並不是找到競爭條件的不好方法。

+0

+1代碼評論。代碼評論總是一件好事! – 2010-06-28 20:00:58

1

它也可以是一個不受保護的資源,它可以解釋不一致的行爲(尤其是如果在單個內核上工作正常,而不是在雙核上)。在任何情況下,代碼審查(對於競爭條件和非線程安全的源代碼)都可能是解決方案的最短路徑。

2

因此,對我來說,大錘的方法是以下,需要很多的耐心,可以在最好的情況下讓你走上正確的軌道。我用這個來弄清楚這個特定問題正在發生什麼。 我一直在使用tracepoints,一個在可疑的高級函數的開頭,一個在最後。向下移動跟蹤點。如果在函數的開頭添加跟蹤點會導致您的bug停止,請將跟蹤點向下移動,直到您可以再次重現條件。這個想法是,如果將跟蹤點放置在最終觸發不安全代碼的調用之後,跟蹤點不會影響定時,但是如果您之前放置它,則會影響定時。另外,請注意你的輸出窗口。你的錯誤發生在哪些消息之間?您也可以使用跟蹤點來縮小此範圍。

一旦將您的bug縮小到可管理的代碼區域,您可以拋出斷點並查看其他線程現在正在做什麼。

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