I'm having a hard time debugging this issue: https://github.com/cnjinhao/nana/issues/445
I have previously asked about LTO vs static object initialization and edited the library's code to implement Meyer's singletons so that the correct order of initialization happens. Hello worlds still crash, although library's functions have mostly dissappeared from stack traces:
#include <nana/paint/graphics.hpp>
int main()
{
nana::paint::font f;
}
Thread 1 received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 0x00000000004985cf in std::type_info::operator==(std::type_info const&) const ()
#1 0x0000000000455180 in __cxxabiv1::__vmi_class_type_info::__do_dyncast(long long, __cxxabiv1::__class_type_info::__sub_kind, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info const*, void const*, __cxxabiv1::__class_type_info::__dyncast_result&) const ()
#2 0x00000000004eae07 in __dynamic_cast ()
#3 0x00000000004e6625 in bool std::has_facet<std::ctype<char> >(std::locale const&) ()
#4 0x00000000004e1f74 in std::basic_ios<char, std::char_traits<char> >::_M_cache_locale(std::locale const&) ()
#5 0x00000000004e20c0 in std::basic_ios<char, std::char_traits<char> >::init(std::basic_streambuf<char, std::char_traits<char> >*) ()
#6 0x00000000004dfe2b in std::ios_base::Init::Init() ()
#7 0x0000000000431f2f in __static_initialization_and_destruction_0(int, int) [clone .lto_priv.4] ()
#8 0x0000000000431f59 in _GLOBAL__sub_I__ZN4nana6detail18drawable_impl_typeC2Ev ()
#9 0x00000000004398c9 in global constructors keyed to 65535_0_objects.a_0x8e.19316 ()
#10 0x00000000004432b3 in __do_global_ctors ()
at E:/GitHub/MINGW-packages/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:67
#11 0x00000000004432fb in __main ()
at E:/GitHub/MINGW-packages/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:83
#12 0x000000000040131c in __tmainCRTStartup ()
at E:/GitHub/MINGW-packages/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:329
#13 0x00000000004014c9 in mainCRTStartup ()
at E:/GitHub/MINGW-packages/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:223
Compiling with -O0 -g -fno-omit-frame-pointer -fno-inline -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -fasynchronous-unwind-tables -fstack-clash-protection have resulted in somewhat longer stack traces, but still nothing to search for.
Even if I stuff the library with unbuffered debug prints nothing appears on the screen - the programs seems to crash before even first global object is constructed. I have used strace (from Git Bash) and verified that the executable loads all correct shared libraries.
I'm looking for anything that could help me debug the issue. Unfortunately this is a Windows-only crash so running this with uftrace or sanitizers is not possible. Using GCC 8.3.1.
The cause of the crash was that the nana library had -static-libgcc -static-libstdc++ in its CMake files as public dependency. The executable and all other libraries had them linked dynamically. Suprisingly, there were no symbol clashes but the standard library code in the executable was corrupted.
Solved by removing these flags from nana's CMake files.
Related
I am using aws sdk for linux to transfer file to s3. I have compiled the shared library of aws sdk.
Transfer of file fails with bad alloc error so thought to explore the example given by aws-sdk.
I am trying to run the example to list the bucket on s3 link.
Compiling the application using command:
g++ testingAws.cpp -I . -L . -laws-cpp-sdk-transfer -laws-cpp-sdk-core -laws-cpp-sdk-s3
Everytime the executables terminates with message:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Bad alloc happens when it invokes the function:
AwsDoc::S3::PutObject(bucket_name, object_name, clientConfig);
Any suggestion if I am missing something. As well how to debug bad alloc issue.
I tried to list the bucket on my s3 server.
Backtrace:
Backtrace: terminate called after throwing an instance of 'std::bad_alloc' what():
std::bad_alloc Thread 1 "a.out" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737314626112) at ./nptl/pthread_kill.c:44 44
./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737314626112) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=140737314626112) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=140737314626112, signo=signo#entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007ffff6b2d476 in __GI_raise (sig=sig#entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff6b137f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff6dd5bbe in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff6de124c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff6de12b7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x00007ffff6de1518 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#9 0x00007ffff6dd57cc in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00007ffff6e7ee6f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#11 0x00007ffff6e7f22d in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#12 0x000055555555b58d in Aws::S3::Model::PutObjectRequest::SetBucket(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#13 0x000055555555a78b in AwsDoc::S3::PutObject(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Aws::Client::ClientConfiguration const&) ()
#14 0x0000000000000000 in ?? ()
(gdb
It's been resolved. I was using header files that were from windows. There was no compilation error so thought everything should work as expectation but later I have taken header files from the Linux machine and that has resolved it.
I try to understand how to overcome problems with the dual ABI introduced in GCC 5. However, I don't manage to do it. Here is a very simple example to reproduce errors. The version of GCC I use is 5.2. As you can see, my main function (in main.cpp file) is quite simple:
// main.cpp
#include <iostream>
#include <string>
int main()
{
std::string message = "SUCCESS!";
std::cout << message << std::endl;
}
When I type
/home/aleph/gcc/5.2.0/bin/g++ main.cpp
I get the following error message:
/tmp/ccjsTADd.o: In function `main':
main.cpp:(.text+0x26): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
main.cpp:(.text+0x43): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
main.cpp:(.text+0x5c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
main.cpp:(.text+0x8c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
collect2: erreur: ld a retourné 1 code d'état d'exécution
If I change the value of _GLIBCXX_USE_CXX11_ABI to 0, the problem disappears.
But, how to make things work with the default ABI?
EDIT: simpler question (removed cmake script)
I found the solution by adding more verbosity to gcc (-v flag). If you have the same problem, you need to tell gcc to search for libraries in the repository containing the libstdc++ version of your distribution. In other words, you should try something like this:
/home/aleph/gcc/5.2.0/bin/g++ -L /home/aleph/gcc/5.2.0/lib64 main.cpp
The linking step should be correctly performed after that. However, you may not be able to run your program. Entering
./a.out
may lead to the following error:
./a.out: relocation error: ./a.out: symbol _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_, version GLIBCXX_3.4.21 not defined in file libstdc++.so.6 with link time reference
Indeed, you can check that your executable depends on the wrong version of libstdc++ by typing
ldd a.out
which should lead to something like that:
linux-vdso.so.1 => (0x00007ffebb722000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000003a71400000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x0000003d03a00000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x0000003a71000000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000003d02e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d02a00000)
Set LD_LIBRARY_PATH to the path to your own version of libstdc++ will solve the problem:
LD_LIBRARY_PATH=/home/aleph/gcc/5.2.0/lib64 ./a.out
Hope it helps!
EDIT: as noticed by Marc, it is possible to modify the rpath, instead of modifying the environment variable LD_LIBRARY_PATH. Here is a CMake configuration script to do it.
project (example CXX)
add_executable(main main.cpp)
if(GCC_ROOT)
set(CMAKE_CXX_COMPILER ${GCC_ROOT}/bin/g++)
target_link_libraries(main ${GCC_ROOT}/lib64/libstdc++.so)
link_directories(${GCC_ROOT}/lib64)
endif(GCC_ROOT)
This script can be used with the usual combo
cmake ..
make
in a 'build' subdirectory. But it is also possible to choose our own compilers by providing the path to the root of our GCC distribution:
cmake -D GCC_ROOT=/home/aleph/gcc/5.2.0 ..
make
The script is written so that the version of libstdc++ corresponds to the version of the input GCC distribution.
Not sure what issue I am having here.
Mac clang 3.1 cmake
gtest
few files
using few C++11 features
I have downloaded and installed XCode build tools
CMAKE_CXX_FLAGS = -Wall -std=c++0x -stdlib=libc++ -v
builds fine with output...
[100%] Building CXX object CMakeFiles/soupbintcptest.dir/soupmessages_tests.cpp.o
clang version 3.1 (tags/RELEASE_31/final)
Target: x86_64-apple-darwin11.3.0
Thread model: posix
Linking dumps a slew of errors. ABI errors? I know there is this C++11 namespace mangling thing happening.
Undefined symbols for architecture x86_64:
They are all things in the std:: namespace that will not link like:
"std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::_Setprecision)", referenced from:
testing::AssertionResult testing::internal::FloatingPointLE<float>(char const*, char const*, float, float) in libgtest.a(gtest-all.cc.o)
testing::AssertionResult testing::internal::FloatingPointLE<double>(char const*, char const*, double, double) in libgtest.a(gtest-all.cc.o)
testing::Message::Message() in libgtest.a(gtest-all.cc.o)
or
"std::cerr", referenced from:
testing::internal::GTestLog::GetStream() in libgtest.a(gtest-all.cc.o)
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()", referenced from:
testing::UnitTest::AddTestPartResult(testing::TestPartResult::Type, char const*, int, testing::internal::String const&, testing::internal::String const&) in libgtest.a(gtest-all.cc.o)
testing::internal::SingleFailureChecker::~SingleFailureChecker() in libgtest.a(gtest-all.cc.o)
testing::internal::StringStreamToString(std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >*) in libgtest.a(gtest-all.cc.o)
testing::TestInfo::TestInfo(char const*, char const*, char const*, char const*, void const*, testing::internal::TestFactoryBase*) in libgtest.a(gtest-all.cc.o)
testing::TestInfo::~TestInfo() in libgtest.a(gtest-all.cc.o)
testing::internal::ReportInvalidTestCaseType(char const*, char const*, int) in libgtest.a(gtest-all.cc.o)
testing::internal::XmlUnitTestResultPrinter::PrintXmlUnitTest(__sFILE*, testing::UnitTest const&) in libgtest.a(gtest-all.cc.o)
...
I believe I have built gtest with the same clang++ version. Not sure what else is going on here to drive these issues.
I've seen similar errors to yours when the linker is pulling in a different c++ library to the one that matches what the compiler is building for. In your case, you are only modifying the compiler flags, but the linker doesn't know your choice and is likely linking to the wrong C++ library.
If you are able to use CMake 3.2 or later, then rather than modifying the C++ compiler flags directly, I'd recommend you just tell CMake you want to use C++11 and then let it work out the appropriate compiler and linker flags for you. This can be done by adding the following before your project() call:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
This and related CMake features are discussed in detail in this article.
There is nothing C++11 about name mangling, it's been going on since the very first C++ implementations. However, do not forget that you must have built gtest for the same stdlib switch, because it can't find the Standard libraries.
Why does STL code seem to be statically linked into the Boost dynamic libraries on Darwin?
When I build Boost 1.42/1.46.1/1.49 on OS X with gcc 4.6.1 and toolset=darwin, I find that the resulting libraries statically include a lot of STL code, such as std::basic_string<char> and std::basic_string<wchar_t>.
Building on OS X 10.6.8, I get the following results:
% otool -L /usr/local/boost-1.46.1/lib/libboost_system.dylib
boost-1.46.1/lib/libboost_system.dylib:
libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
/usr/local/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
Based on the 'otool -L' output, it's clear that libstdc++ is not dynamically linked with the library. By comparison, on Ubuntu 12.04 LTS, libboost_system.so 1.46.1 shows the following linking:
% ldd /usr/local/lib/libboost_system.so
linux-vdso.so.1 => (0x00007fff495ff000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fec4edb4000)
libstdc++.so.6 => /usr/local/lib64/libstdc++.so.6 (0x00007fec4ea82000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fec4e788000)
libgcc_s.so.1 => /usr/local/lib64/libgcc_s.so.1 (0x00007fec4e573000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fec4e355000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fec4df98000)
/lib64/ld-linux-x86-64.so.2 (0x00007fec4f1e4000)
In this case libstdc++ has clearly been dynamically linked. On the OS X side, this is how I know that STL code has been included directly in the Boost library:
% nm -gfj /usr/local/boost-1.46.1/lib/libboost_system.dylib | c++filt --format=gnu-v3 | egrep "^std::basic_string"
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_disjunct(char const*) const
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(char const*, unsigned long) const
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(char const*, unsigned long, unsigned long) const
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long) const
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(char, unsigned long) const
... [180 more lines] ...
Just to pick on one example:
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(char const*, unsigned long) const
std::basic_string is a template class, and does not exist in libstdc++.dylib. It was instantiated when the boost library was compiled, and (rightly) included there - because Boost.System uses it.
I suspect (but don't know) that this is true for all of the calls you see.
I'm debugging a daemon in gdb by attaching gdb to the daemon process, and setting gdb to follow the child when it forks. It would be very useful to somehow figure out where the function I am in currently, is located - i.e. if the function were present in the daemon binary or a shared object that were loaded. If it were a shared object, it would be useful to have its name or path.
Can this be done?
(gdb) info symbol 0x002a4995
_IO_new_file_write + 7 in section .text of /lib/i386-linux-gnu/libc.so.6
It would be very useful to somehow figure out where the function I am
in currently, is located
You can do it by comparing function address with addresses of currently loaded shared libraries.
(gdb) bt
#0 0x00130416 in __kernel_vsyscall ()
#1 0x002fc683 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:82
#2 0x002a4995 in _IO_new_file_write (f=0x3b4500, data=0xb7ffd000, n=4) at fileops.c:1276
#3 0x002a4874 in new_do_write (fp=0x3b4500, data=0xb7ffd000 "123\n", to_do=4) at fileops.c:530
#4 0x002a5eee in _IO_new_do_write (fp=0x3b4500, data=0xb7ffd000 "123\n", to_do=4) at fileops.c:503
#5 0x002a6235 in _IO_new_file_overflow (f=0x3b4500, ch=10) at fileops.c:889
#6 0x002a6e4b in __GI___overflow (f=0x3b4500, ch=10) at genops.c:248
#7 0x0029da6f in _IO_putc (c=10, fp=0x3b4500) at putc.c:33
#8 0x001b835b in __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char> >::overflow(int) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#9 0x001b966e in std::ostream::put(char) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#10 0x001b98e4 in std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#11 0x001b8cae in std::ostream::operator<<(std::ostream& (*)(std::ostream&)) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#12 0x08048ac5 in main () at so-test.cpp:10
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x00110830 0x001275af Yes (*) /lib/ld-linux.so.2
0x00176e50 0x001e93a8 Yes (*) /usr/lib/i386-linux-gnu/libstdc++.so.6
0x0021df50 0x00234cf8 Yes (*) /lib/i386-linux-gnu/libgcc_s.so.1
0x00250be0 0x0035ebd4 Yes /lib/i386-linux-gnu/libc.so.6
0x003bb4b0 0x003d6ab8 Yes /lib/i386-linux-gnu/libm.so.6
(*): Shared library is missing debugging information.
(gdb)
For example _IO_new_file_write address is 0x002a4995, which lies between 0x00250be0 and 0x0035ebd4 where /lib/i386-linux-gnu/libc.so.6 was loaded. That is _IO_new_file_write belongs to libc.so.6 library.