C++使用不同的gcc优化的不同错误

C++ Different errors using different gcc optimizations

本文关键字:优化 错误 gcc C++      更新时间:2023-10-16

使用不同的gcc优化,我的程序由于不同的操作系统信号而死亡,我想知道原因是否相同。

由于使用O2编译的c++多线程程序中的abort(),我得到了一个核心转储。

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

我只是无法找出原因,因为它似乎是在本地std::vector析构函数中。。没有

(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  ...

通过深入研究代码,我意识到向量是使用来自其他线程的另一个向量组合初始化的,重点是,没有使用互斥锁来实现这一点。为了简化我写了这个代码来复制它。(请忽略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进行编译它完成得很好。

感谢您抽出时间

当工作线程访问共享向量时,您正在锁定互斥对象;但当主线程修改它时不会。您需要保护对共享可变数据的所有访问。

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

您还可以考虑使用条件变量在向量更改时通知工作线程,这样工作线程就不会占用忙于等待的资源。