使用openmp锁定的可疑分段错误

问题描述 投票:0回答:1

我的程序因分段错误而终止。我将代码简化为:

#include <string>
#include <omp.h>
#include <iostream>

namespace ns { // Holds three strings
    static const std::string A = "a";
    static const std::string B = "b";
    static const std::string C = "c";
}

namespace ns2 {
    // Wraps an ostream and a lock; for example, concurrent access
    // can be implemented this way
    class wrapper { 
    private:
        std::ostream &_stream;
        omp_lock_t _lock;
    public:
        wrapper(std::ostream &stream) : _stream(stream)
        {
            omp_init_lock(&_lock);
        }
        // Segmentation Fault also occurs without destructor
        ~wrapper()
        {
            omp_destroy_lock(&_lock);
        }
    };
    // Wrap stdout
    static wrapper cout(std::cout);
}

namespace ns3 {
    struct somestruct {
        const std::string _0;   
        const std::string _a;
        const std::string _b;
        const std::string _c;
        somestruct(std::string o, std::string a, std::string b, std::string c)
            : _0(o), _a(a), _b(b), _c(c) { }
    };
}

int main(int argc, char *argv[])
{   
    ns3::somestruct cont("0", ns::A, ns::B, ns::C);
    return 0;
}

我正在MacOS上编译:

系统版本:OS X 10.11.6(15G22010)内核版本:Darwin 15.6.0

使用g++-7

g ++-7(自制GCC 7.5.0_1)7.5.0版权所有(C)2017自由软件基金会,Inc.这是免费软件;请参阅复制条件的来源。没有保证;甚至不是出于适销性或特定目的的适用性。

并且命令行是g++-7 file.cpp -O1 -fopenmp

-O2-O3也会发生分段错误,但-O0不会发生。奇怪的是,它仅在此计算机上发生,而在我的其他计算机或godbolt上都没有。

我在可执行文件上运行了valgrind。这是输出:

== 54305 == Memcheck,内存错误检测器== 54305 ==版权所有(C)2002-2017,由Julian Seward等人提供GNU GPL。== 54305 ==使用Valgrind-3.15.0和LibVEX;使用-h重新运行以获取版权信息== 54305 ==命令:./ a.out== 54305 ==== 54305 ==读取的大小为1无效== 54305 == at 0x100000906:void std :: __ cxx11 :: basic_string,std :: allocator> :: _ M_construct(char const *,char const *,std :: forward_iterator_tag)[clone .isra.23](basic_string.h :338)== 54305 ==通过0x1000009EC:main(basic_string.h:236)== 54305 ==地址0x4d55545a4d55545a未堆栈,未分配或(最近)释放== 54305 ==== 54305 ==信号11从线程0的队列中删除

后跟无限循环

== 54305 ==从线程0的队列中删除信号11

此后我必须使用kill来停止memcheck,它不会对Ctrl+C做出反应。另请参见this question,以获取来自valgrind的类似响应。但是,这里似乎有不同的原因。

目前我无法使用gdb,因为我必须对其进行代码签名(我认为仅通过终端/ ssh是不可能的。)

另一个有趣的事情是,如果我将ns3::somestruct cont("0", ns::A, ns::B, ns::C);行注释掉,而不是简单地打印

分段错误:11

程序的输出变为

a.out(54371,0x7fff77d7d000)malloc:对象0x4d55545a4d55545a的***错误:未分配要释放的指针***在malloc_error_break中设置断点以进行调试中止陷阱:6

我不知道细分错误的来源。我错过了什么吗?

编辑

我设法使gdb工作。这是输出:

[[进程55870的新线程0x1703]程序收到信号SIGSEGV,分段故障。警告:`/private/tmp/gcc@7-20200229-63593-evr5eg/gcc-7.5.0/build/x86_64-apple-darwin15.6.0/libstdc ++-v3 / src / .libs / compatibility-atomic-c ++ 0x.o':无法打开以读取符号:没有此类文件或目录。[接着是更多这样的警告]

程序收到信号SIGSEGV,分段故障。std :: __ cxx11 :: basic_string,std :: allocator> :: _ M_construct(this = 0x7fff5fbffb70,__beg = 0x4d55545a4d55545a,__end =)(gdb)其中#0 std :: __ cxx11 :: basic_string,std :: allocator> :: _ M_construct(this = 0x7fff5fbffb70,__beg = 0x4d55545a4d55545a,__end =)#1 0x0000000100000a2f在/usr/local/Cellar/gcc@7/7.5.0_1/include/c++/7.5.0/bits/basic_string.h:236中的main(argc =,argv =)中

我还是不明白,为什么会这样。我最近更新了自制程序从此以后似乎一直出现此“错误”

,此后便发生了此错误。关于哪个库可能需要更新或类似内容的任何想法?

编辑2

再次,注释掉main的第一行解决了问题:

a.out(55934,0x7fff77d7d000)malloc:***对象0x4d55545a4d55545a的错误:未分配要释放的指针***在malloc_error_break中设置断点以进行调试程序收到信号SIGABRT,异常终止。来自/usr/lib/system/libsystem_kernel.dylib的__pthread_kill()中的0x00007fff88204f06(gdb)其中来自/usr/lib/system/libsystem_kernel.dylib的__pthread_kill()中的#0 0x00007fff88204f06来自/usr/lib/system/libsystem_pthread.dylib的pthread_kill()中的#1 0x00007fff8c40d4ec#2 0x00007fff8b7f06df来自/usr/lib/system/libsystem_c.dylib的中止()#3 0x00007fff88273041在(/usr/lib/system/libsystem_malloc.dylib)中的free()中/usr/lib/system/libsystem_c.dylib中的__cxa_finalize_ranges()中的#4 0x00007fff8b7f1463#5 0x00007fff8b7f1767在/usr/lib/system/libsystem_c.dylib的出口()中#6 0x00007fff939de5b4在/usr/lib/system/libdyld.dylib中的start()中#7 0x0000000000000000 in ?? ()

编辑3

[otool -Lldd在本机上不可用,但根据this discussion应该等效)给出以下输出:

a.out:/ usr / local / opt / gcc @ 7 / lib / gcc / 7 / libstdc ++。6.dylib(兼容版本7.0.0,当前版本7.24.0)/usr/local/opt/gcc@7/lib/gcc/7/libgomp.1.dylib(兼容版本2.0.0,当前版本2.0.0)/usr/lib/libSystem.B.dylib(兼容版本1.0.0,当前版本1226.10.1)/usr/local/lib/gcc/7/libgcc_s.1.dylib(兼容版本1.0.0,当前版本1.0.0)

[我将在重新安装gcc@9时立即添加会发生的情况,但我记得以前的安装中,其行为应该相同。

该行为与g++-9相同。 otool -L输出显示dylib的版本9变体,除了/usr/lib/libSystem.B.dylib在这种情况下相同。

任何人都可以重现此错误吗?

编辑4

我在更新自制软件之前在较旧版本的可执行文件上使用了otool -L。它引用

/ usr/local/opt/gcc@7/lib/gcc/7/libstdc++.6.dylib(兼容版本7.0.0,当前版本7。23。0)

而所有其他库均为相同版本。此外,g++-9编译的可执行文件还引用了7.24.0版。 也许这会导致错误?如何重新安装此较早版本的libstdc ++以测试此假设?

我强迫brew重新安装g++版本7.1.0,该版本使用libstdc ++的7.23.0版本。该错误仍然存​​在。

我的程序因分段错误而终止。我将代码简化为:#include #include #include namespace ns {//包含三个字符串...

c++ macos segmentation-fault g++ openmp
1个回答
0
投票

经过大量的尝试后,我最终决定将操作系统升级到macOS Mojave

。这在I brew reinstalled everything之后解决了问题。 (我注意到诸如gnuplot之类的软件存在更多问题,导致程序无法正常启动。)
© www.soinside.com 2019 - 2024. All rights reserved.