2014-03-29 35 views
0

細基本操作Pthreaded程序在Linux機器上導致分段錯誤。適用於Cygwin64

創建一個程序來測試用C多線程和單線程堆實現++。該程序基於全局數據結構來構建和處理堆,所述全局數據結構由包含稍微隨機數的2^20無符號整數的STL向量2^8 STL向量組成。

主數據結構正確初始化,我的程序當前分爲兩個測試階段,其中一個階段調用函數以順序方式執行算法,將結果轉儲到大小與全局數組相同的全局數組中在上述數據結構(2^8)中的子矢量,並且這個數組中的每個元素指定在矢量的主矢量中的相同索引處的子矢量的結果。

第二階段完全相同,但並行地使用多個pThreads從主向量並行處理子向量組。第二階段將結果存儲在與第一個分開的數組中,這兩個結果數組用於比較和校正檢查。

所以主要的數據結構,矢量矢量只能從程序的兩個階段讀取。每個階段寫入一個不同的全局數組,但是在索引中指定了該數組中的不同元素。

該算法從每個子向量中構建一個堆,並以順序方式對該子向量中的元素執行一系列更新鍵操作,直到它耗盡了子向量中的所有元素。第一階段通過按順序處理每個子矢量來執行此操作,第二階段通過並行處理子矢量組來執行此操作。

問題是,當我在Windows機器上執行Cygwin64下的程序時,程序正確執行。沒有錯誤,正確的結果,一切工作都很好。即使使用較小的數據集進行測試也顯示該算法正在正確執行。

的問題

下面是程序的執行Cygwin64。

D-Value: 64 
List Set Size: 256 
Sub-List Size: 1048576 
K-Value: 104857 
D-Heap Offset: 63 
Ad-Heap Offset: 63 


Number Of POSIX Threads: 4 

Initializing the list of sub-lists to be be processed. 

Please wait while building answer array by serially processing the sub-lists. 

Finished testing for the kth element in each sub list using CPU serially. 

CPU Wall-Clock Time: 45.2943s 
CPU Processor Time: 45.286s 

Begin testing for the kth element in each sub list using CPU with POSIX threads. 

Finished testing for the kth element in each sub list using CPU and parallel POSIX  threads. 

POSIX Threaded CPU Wall-Clock Time: 12.7866s 
POSIX Threaded CPU Processor Time: 50.202s 

The results are correct! 

一切工作正常,即使我通過輸入降低POSIX線程的數量,或改變數據結構的大小,它工作正常。如果我足夠減小數據結構的大小以檢查結果(例如,256個元素的256個子向量),我可以看到算法返回的結果是正確的。所以算法應該正確執行。

如果我任何Linux機器上執行同一個程序:

D-Value: 64 
List Set Size: 256 
Sub-List Size: 1048576 
K-Value: 104857 
D-Heap Offset: 63 
Ad-Heap Offset: 63 


Number Of POSIX Threads: 4 

Initializing the list of sub-lists to be be processed. 

Please wait while building answer array by serially processing the sub-lists. 
Segmentation Fault (core dumped) 

它甚至不讓它通過的點,在那裏我只是順序執行的算法。但是,如果我減少子向量的數量爲1。

D-Value: 64 
List Set Size: 1 
Sub-List Size: 1048576 
K-Value: 104857 
D-Heap Offset: 63 
Ad-Heap Offset: 63 


Number Of POSIX Threads: 1 

Initializing the list of sub-lists to be be processed. 

Please wait while building answer array by serially processing the sub-lists. 

Finished testing for the kth element in each sub list using CPU serially. 

CPU Wall-Clock Time: 0.23356s 
CPU Processor Time: 0.19s 

Begin testing for the kth element in each sub list using CPU with POSIX threads. 

Finished testing for the kth element in each sub list using CPU and parallel POSIX  threads. 

POSIX Threaded CPU Wall-Clock Time: 0.237998s 
POSIX Threaded CPU Processor Time: 0.19s 

The results are correct! 

如果增加子向量的數目爲任意大小大於1,則分段錯誤回報。所以我使用gdb來試着看看我是否可以確定分段故障發生的位置。

Please wait while building answer array by serially processing the sub-lists. 

Program received signal SIGSEGV, Segmentation fault. 
_int_malloc (av=0x7ffff7398740 <main_arena>, bytes=<optimized out>) 
at malloc.c:3445 
3445 malloc.c: No such file or directory. 
(gdb) bt 
#0 _int_malloc (av=0x7ffff7398740 <main_arena>, bytes=<optimized out>) 
    at malloc.c:3445 
#1 0x00007ffff705a4d0 in __GI___libc_malloc (bytes=419680) at malloc.c:2859 
#2 0x0000000000401eaf in Heap_Build (main_list_index=1) at ad_heap.cpp:312 
#3 0x00000000004018bc in main (argc=7, argv=0x7fffffffdf48) at ad_heap.cpp:203 

所以程序在函數Heap_Build中的malloc調用失敗。這是基本上通過構建堆執行算法的函數,在來自子向量的堆上執行更新密鑰操作序列。程序的第一階段以順序方式調用這個函數,第二階段允許每個pThread調用函數來處理它們的子向量組。

unsigned int Heap_Build(unsigned int main_list_index) 
{ 
    unsigned int num_of_nodes = 0; 
    unsigned int *heap = (unsigned int*) malloc((k+usage_offset) * sizeof(unsigned int)); 
    unsigned int sublist_value; 

    for(int i = 0; i < k; i++) 
    { 

     sublist_value = main_list.at(main_list_index).at(i); 

     num_of_nodes = Heap_Insert_Node(heap, sublist_value, num_of_nodes); 
    } 


    for(int i = k; i < sub_list_size; i++) 
    { 
     sublist_value = main_list.at(main_list_index).at(i); 


     if(sublist_value < heap[usage_offset]) 
     { 
      Heap_Update_Key_CPU(heap, 0, sublist_value, num_of_nodes); 
     } 
    } 
    return heap[usage_offset]; 
    free(heap); 
} 

似乎有不被任何在此代碼可疑,k是堆,k的大小+ usage_offset是表示堆的陣列的大小。返回值只是堆的根。用作堆的無符號整數的malloc'd數組結構在使用後被釋放。

我真的不知道爲什麼上面的代碼將在Cygwin64正確執行,給予正確的結果,一切,並沒有任何Linux機器上。

回答

0

malloc中的崩潰是內存損壞的標誌。
使用valgrind和co(mcheck,電子圍欄,tcmalloc等),通常有幫助。 (例如github)發佈完整的源代碼(甚至更好,最小的測試用例,它仍然顯示問題)。如果你希望人們修復它的運動程序,那麼可以發佈完整的源代碼。