My program terminated with a Segmentation Fault. I reduced the code down to this:
#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;
}
I am compiling on MacOS:
System Version: OS X 10.11.6 (15G22010)
Kernel Version: Darwin 15.6.0
using g++-7
:
g++-7 (Homebrew GCC 7.5.0_1) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
and the command line is
g++-7 file.cpp -O1 -fopenmp
The Segmentation Fault also occurs for -O2
and -O3
, but not for -O0
. Strangely, it only occurs on this machine and none of my other machines or godbolt.
I ran valgrind
on the executable. This is the output:
==54305== Memcheck, a memory error detector
==54305== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==54305== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==54305== Command: ./a.out
==54305==
==54305== Invalid read of size 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== by 0x1000009EC: main (basic_string.h:236)
==54305== Address 0x4d55545a4d55545a is not stack'd, malloc'd or (recently) free'd
==54305==
==54305== Signal 11 being dropped from thread 0's queue
followed by an infinite loop of
==54305== Signal 11 being dropped from thread 0's queue
I have to use kill
to stop memcheck after that, it does not react to Ctrl+C
. See also this question for a similar response from valgrind
. However, there seems to be a different cause here.
I cannot use gdb
at the moment, because I have to codesign it (which I don't think is possible solely via terminal/ssh
).
Another interesting thing is that if I comment out the line ns3::somestruct cont("0", ns::A, ns::B, ns::C);
instead of simply printing
Segmentation fault: 11
the output of the program becomes
a.out(54371,0x7fff77d7d000) malloc: *** error for object 0x4d55545a4d55545a: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
I do not see, where the Segmentation Fault would come from. Did I miss something?
Edit
I have managed to get gdb
working. This is the output:
[New Thread 0x1703 of process 55870]
Program received signal SIGSEGV, Segmentation fault.
warning: `/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': can't open to read symbols: No such file or directory.
[Followed by a lot more warnings like that]
Program received signal SIGSEGV, Segmentation fault.
std::__cxx11::basic_string, std::allocator >::_M_construct (this=0x7fff5fbffb70, __beg=0x4d55545a4d55545a , __end=)
(gdb) where
#0 std::__cxx11::basic_string, std::allocator >::_M_construct (this=0x7fff5fbffb70, __beg=0x4d55545a4d55545a , __end=)
#1 0x0000000100000a2f in main (argc=, argv=) at /usr/local/Cellar/gcc@7/7.5.0_1/include/c++/7.5.0/bits/basic_string.h:236
I still don't understand, why this happens. I recently updated homebrew and ever since then this "bug" seems to occur and since then this bug occurs. Any ideas on which library might need an update or similar?
Edit 2
Again, commenting out the first line of main
moves the problem:
a.out(55934,0x7fff77d7d000) malloc: *** error for object 0x4d55545a4d55545a: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Program received signal SIGABRT, Aborted.
0x00007fff88204f06 in __pthread_kill () from /usr/lib/system/libsystem_kernel.dylib
(gdb) where
#0 0x00007fff88204f06 in __pthread_kill () from /usr/lib/system/libsystem_kernel.dylib
#1 0x00007fff8c40d4ec in pthread_kill () from /usr/lib/system/libsystem_pthread.dylib
#2 0x00007fff8b7f06df in abort () from /usr/lib/system/libsystem_c.dylib
#3 0x00007fff88273041 in free () from /usr/lib/system/libsystem_malloc.dylib
#4 0x00007fff8b7f1463 in __cxa_finalize_ranges () from /usr/lib/system/libsystem_c.dylib
#5 0x00007fff8b7f1767 in exit () from /usr/lib/system/libsystem_c.dylib
#6 0x00007fff939de5b4 in start () from /usr/lib/system/libdyld.dylib
#7 0x0000000000000000 in ?? ()
Edit 3
otool -L
(ldd
is not available on this machine, but according to this discussion it should be equivalent) gives the following output:
a.out:
/usr/local/opt/gcc@7/lib/gcc/7/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.24.0)
/usr/local/opt/gcc@7/lib/gcc/7/libgomp.1.dylib (compatibility version 2.0.0, current version 2.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
/usr/local/lib/gcc/7/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
I will add what happens for gcc@9
as soon as it is reinstalled, but I remember from a previous install, that the behaviour should be identical.
The behaviour is identical with g++-9
. The otool -L
output shows the version 9 variants of the dylibs except for /usr/lib/libSystem.B.dylib
which is identical in this case.
Can anyone reproduce this bug?
Edit 4
I used otool -L
on an older version of the executable I compiled before I updated homebrew. It references
/usr/local/opt/gcc@7/lib/gcc/7/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.23.0)
while all other libraries are the same version. Additionally, the g++-9
compiled executable also references version 7.24.0. Maybe this causes the bug?
How do I reinstall this older version of libstdc++ to test this hypothesis?
I forced brew to reinstall g++
version 7.1.0 which uses version 7.23.0 of libstdc++. The bug persists.
ldd
on the generated executable? – Jérôme Richardotool
the version 7. Additionally, from the GCC documentation we can see that GCC should use an older version (but maybe the version 7.23 is compatible with 6.xx versions, although that would be surprising). – Jérôme Richard