2014-09-01 38 views
1

使用不同的gcc優化我的程序由於不同的OS信號而死亡,我不知道原因是否相同。C++不同的錯誤使用不同的gcc優化

由於在使用O2編譯的C++多線程程序中發生abort(),所以我得到了一個核心轉儲。

Program terminated with signal 6, Aborted. 
#0 0x00007ff2572d28a5 in raise() from /lib64/libc.so.6 

我只是沒能找出哪個是原因,因爲它似乎是在本地的std ::矢量析構函數..這毫不 意義對我來說。

(gdb) thread 1 
[Switching to thread 1 (Thread 0x7ff248d6c700 (LWP 16767))]#0 0x00007ff2572d28a5 in raise() from /lib64/libc.so.6 
(gdb) bt 
#0 0x00007ff2572d28a5 in raise() from /lib64/libc.so.6 
#1 0x00007ff2572d4085 in abort() from /lib64/libc.so.6 
#2 0x00007ff25730fa37 in __libc_message() from /lib64/libc.so.6 
#3 0x00007ff257315366 in malloc_printerr() from /lib64/libc.so.6 
#4 0x00007ff257317e93 in _int_free() from /lib64/libc.so.6 
#5 0x000000000044dd45 in deallocate (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ext/new_allocator.h:95 
#6 _M_deallocate (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:146 
#7 ~_Vector_base (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:132 
#8 ~vector (this=0x7ff250389610) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:313 
#9 ... 

STUDING更深我意識到,載體使用另一個矢量從其他線程初始化正在添加和 這裏是點代碼,沒有互斥來做到這一點。爲了簡化 我寫了這個代碼來重現那個。 (請忽略stopThread是不受保護的)

void* doWork(void*) 
{ 
    while(!stopThread) 
    { 
     double min = std::numeric_limits<int>::max(); 
     double max = std::numeric_limits<int>::min(); 
     pthread_mutex_lock(&_mutex); 
     std::vector<double> localVector = (sharedVector); 
     sharedVector.clear(); 
     pthread_mutex_unlock(&_mutex); 

     for(unsigned int index = 0; index < localVector.size(); ++index) 
     { 
      std::cout << "Thread 2 " << localVector[index] << ", " << std::endl; 
      if(min > localVector[index]) 
      { 
       min = localVector[index]; 
      } 
      if(max < localVector[index]) 
      { 
       max = localVector[index]; 
      } 
     } 
    } 
    return NULL; 
} 

int main() 
{ 
    pthread_mutex_init(&_mutex, NULL); 
    stopThread = false; 

    pthread_create(&_thread, NULL, doWork, NULL); 

    for(int i = 0; i < 10000; i++) 
    { 
     sharedVector.push_back(i); 
     std::cout << "Thread 1 " << i << std::endl; 
     usleep(5000); 
    } 
    stopThread = true; 

    pthread_join(_thread, NULL); 
    pthread_cancel(_thread); 

    std::cout << "Finished! " << std::endl; 
} 

我固定的,但我不能說我解決了這個問題(我知道我固定一個問題,但不是我要找的問題)爲核心發生一次每月或多或少。 所以我決定編譯使用O0來看看如果我可以在覈心文件中看到更多細節,然後我強制程序崩潰。現在,我所擁有的是我期望的Segfault。

Program terminated with signal 11, Segmentation fault. 
#0 0x00007f4598f70cd7 in memmove() from /lib64/libc.so.6 

(gdb) bt 
#0 0x00007f4598f70cd7 in memmove() from /lib64/libc.so.6 
#1 0x000000000045fb84 in std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m<double> (__first=0x7f4580977ba0, __last=0x7f4580977ba8, __result=0x0) 
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:378 
#2 0x0000000000465f01 in std::__copy_move_a<false, double const*, double*> (__first=0x7f4580977ba0, __last=0x7f4580977ba8, __result=0x0) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:397 
#3 0x0000000000465e66 in std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0) 
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:436 
#4 0x0000000000465d6d in std::copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0) 
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_algobase.h:468 
#5 0x0000000000465c84 in std::__uninitialized_copy<true>::uninitialized_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, 
    __result=0x0) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_uninitialized.h:93 
#6 0x0000000000465ad9 in std::uninitialized_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0) 
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_uninitialized.h:117 
#7 0x0000000000465718 in std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, double*, double> (__first=4.3559999999999999, __last=3.1560000000000001, __result=0x0) 
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_uninitialized.h:257 
#8 0x00000000004650f9 in std::vector<double, std::allocator<double> >::vector (this=0x7f4594d90d70, __x=std::vector of length 1, capacity 4 = {...}) 
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:243 
#9 ... 

我找一些文檔,但我發現沒有什麼話說,錯誤類型可以改變由於優化。 但是,我運行上面的代碼,重現了問題,並用O0編譯出現了分段錯誤,但是使用O2 進行編譯,它可以很好地完成。

感謝您的時間

+0

通常這意味着你有一個潛在的問題,隨便只提出自己的一些優化。例如一些未定義的行爲,訪問無效內存。在調試('-Og')中它會崩潰嗎? – NetVipeC 2014-09-01 14:10:50

+0

你的海灣合作委員會已經很老了(目前是4.9)。嘗試安裝一個更新的GCC並使用它的'-fsanitize = address'和'-fsanitize = thread'選項 – 2014-09-01 14:11:55

+0

是的,它在調試模式下會崩潰。沒有可能性升級gcc – lechuck 2014-09-01 15:11:17

回答

9

您在工作線程訪問共享矢量時鎖定互斥鎖;但是當主線程修改它時不會。您需要保護所有對共享可變數據的訪問。

for(int i = 0; i < 10000; i++) 
{ 
    pthread_mutex_lock(&_mutex);    // Add this 
    sharedVector.push_back(i); 
    pthread_mutex_unlock(&_mutex);    // Add this 
    std::cout << "Thread 1 " << i << std::endl; 
    usleep(5000); 
} 

您也可以考慮使用條件變量來通知工作線程時,矢量的變化,使工人不消耗資源忙等待。

相關問題