Linking unwind library statically results in core dump - c++

This code, compiles with g++ using -std=c++11. Linking with g++, when libunwind is linked in statically program crashes after catching in exerciseBug (after rethrow).
LDFLAGS that result in crash:
-Wl,-Bstatic -lunwind -Wl,-Bdynamic -llzma
when libunwind is linked in dynamically, code works as normally. LDFLAGS that result in normal operation:
-Wl,-Bstatic -Wl,-Bdynamic -lunwind -llzma
#include <iostream>
using namespace std;
void exerciseBug()
{
try {
throw exception();
} catch (exception &err) {
cerr << "caught in exerciseBug\n";
throw;
}
}
int main()
{
try {
exerciseBug();
} catch (exception &err) {
cerr << "caught in main\n";
::exit(0);
}
}
Question is why is does libunwind need to be dynamically linked in?
(Running on Ubuntu 16.04; g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609)

Related

Why is this thrown object not caught when using link-time optimization?

Suppose I have a function in a shared library throwing some object, and a main executable calling that function and attempting to catch that object, e.g.
decl.h
#ifndef DECL_H
#define DECL_H
void pitch();
struct MyException {
MyException();
MyException(const MyException&);
~MyException();
};
#endif
pitch.cpp
#include "decl.h"
MyException::MyException() {}
MyException::MyException(const MyException&) {}
MyException::~MyException() {}
void pitch() {
throw MyException();
}
main.cpp
#include <stdio.h>
#include "decl.h"
int main() {
try { pitch(); }
catch (MyException& e) { printf("MyException()\n"); }
catch (...) { printf("[unknown exception]\n"); }
}
Makefile
all:
$(CXX) -shared -fPIC $(CXXFLAGS) $(LTO) pitch.cpp -o libpitch.so
$(CXX) -g $(CXXFLAGS) $(LTO) main.cpp -L. -lpitch
./a.out
If I compile without link-time optimization, all is well:
CXXFLAGS="-g -O2" LTO="" make
c++ -shared -fPIC -g -O2 pitch.cpp -o libpitch.so
c++ -g -g -O2 main.cpp -L. -lpitch
./a.out
MyException()
But once I turn on link-time optimization, the thrown object is no longer caught:
CXXFLAGS="-g -O2" LTO="-flto" make
c++ -shared -fPIC -g -O2 -flto pitch.cpp -o libpitch.so
c++ -g -g -O2 -flto main.cpp -L. -lpitch
./a.out
[unknown exception]
Is this expected behavior? Is this a problem in my C++ code, or something else? This is on macOS 10.14.5:
$ c++ -v
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
This is not expected behavior.
I tested it on linux (ubuntu) with gcc 4.x, 5.x, 6.x, 7.x and 8.x and with clang 6.0. All work just fine with -O2 -flto.
Unfortunately, since I cannot reproduce it (I don't have a Mac) I can't tell you what is wrong, but it isn't your code imho.
EDIT:
I can't in good conscious say there is "nothing wrong" with your code (although I tested it as shown by you - HOWEVER, I needed to set LD_LIBRARY_PATH="." for ./a.out to work (so perhaps you are loading some other library?)) without showing you how I'd write the above code:
//decl.h:
#pragma once
#include <exception>
void pitch();
struct MyException : public std::exception
{
};
//pitch.cpp:
#include "decl.h"
void pitch()
{
throw MyException();
}
// main.cpp:
#include "decl.h"
#include <iostream>
int main()
{
try
{
pitch();
}
catch (MyException const& e)
{
std::cout << "MyException(): " << e.what() << std::endl;
}
catch (...)
{
std::cerr << "[unknown exception]" << std::endl;
}
}

"catch" can't catch exception from library

I have this method in library:
#include <stdexcept>
mytype* myfunc()
{
throw std::runtime_error("is uncatchable");
}
and this in int main() of executable process which links library.
try { myfunc(); }
catch(std::exception const& ex) { std::cout << "handled: " << ex.what() << std::endl; }
catch(...) { std::cout << "something else..." << std::endl; }
And that is the output:
terminate called after throwing an instance of 'std::runtime_error'
what(): is uncatchable
Abort (core dumped)
Question:
Why exception was not catch?
I'm not managing my compiler's flags (icc-11.X), also OS is also not under my control.
List of compiler flags:
-DLINUX -DLINUX_X64 -DGNU_SOURCE -fPIC -Wcheck -Wshadow -Wdeprecated -Wreturn-type -Wcomment -Wmissing-prototypes -Wp64 -Drcsid="__attribute__((used)) rcsid"
-D__EXTENSIONS__ -D__STD_C__ -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -DNDEBUG
__EXCEPTIONS is defined.
May there exist settings for Linux which lead to this?
May there exist settings for compiler which lead to this?

AddressSanitizer / LeakSanitizer Error with -lsupc++ and -stdlib=libc++ on a never called virtual function that writes to a stream

The following code throws an AddressSanitizer Error when compiled on Debian Jessie with clang 3.5.
It appears to be related to the combination of linked libraries, but i have not been able to find something similar on the internet.
Reproduction of the Error
Invocation: clang++ -stdlib=libc++ -lc++abi -fsanitize=address,vptr sample.cpp -lsupc++ -o sample
//sample.cpp
#include <iostream>
class Foo {
virtual void bar() {
std::cerr << std::endl;
}
public:
virtual ~Foo() { }
};
int main() {
Foo foo;
try{
throw 1;
} catch(int i) {
return i;
}
return -1;
}
When omitting compile flag -lc++abi, a LeakSanitizer Runtime Error occurs instead.
When omitting any of the other compile flags, no Error occurs.
What causes the error? Is something wrong with my code or is this an invalid combination of compile flags, and if so, what is causing the conflict?

Undefined reference to symbol X509_free

I'm trying to use the mongodb legacy C++ driver. (Here "legacy" means the production version, fwiw.) On an ubuntu 15.04 host using clang++ 3.6 and boost 1.55 (from the ubuntu package repositories) and using mongo-cxx-driver pulled form git, I compiled the driver and then attempted to compile the test program.
$ clang++ -std=c++14 mongo.cc -pthread -lmongoclient -lboost_thread \
-lboost_system -lboost_regex -lssl -o mo
I see this error:
clang++ -std=c++14 mongo.cc -pthread -lmongoclient -lboost_thread -lboost_system -lboost_regex -lssl -lcrypt -o mo
/usr/bin/ld: /usr/local/lib/libmongoclient.a(ssl_manager.o): undefined reference to symbol 'X509_free##OPENSSL_1.0.0'
/lib/x86_64-linux-gnu/libcrypto.so.1.0.0: error adding symbols: DSO missing from command line
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Clearly I'm missing X509_free(), but it appears that should be in libssl (which is openSSL1.0.0, says dpkg and the library symlink itself).
Many thanks for any tips.
I don't think it's important here, but this is mongo.cc:
#include <cstdlib>
#include <iostream>
#include "mongo/client/dbclient.h" // for the driver
void run() {
mongo::DBClientConnection c;
c.connect("localhost");
}
int main() {
mongo::client::initialize();
try {
run();
std::cout << "connected ok" << std::endl;
} catch( const mongo::DBException &e ) {
std::cout << "caught " << e.what() << std::endl;
}
return EXIT_SUCCESS;
}
You should link against libcrypto.so, not libcrypt.so.

Including Boost asio::write.hpp file stops exceptions from being caught?

After narrowing down everything I see that when I include boost/asio/write.hpp, the exception wont be caught and the application terminates on windows (This app. has requested to terminate...)
However, when I comment just this include line, the exception works perfectly.
#include <stdexcept>
#include <iostream>
#include <boost/asio/write.hpp>
int main() {
try {
throw std::logic_error("aajj");
} catch (std::exception &e) {
std::cout << "Caught:" << e.what() << std::endl;
}
}
invoked build using these gcc settings
g++ -D_WIN32_WINNT=0x0601 -O0 -g3 -Wall -c -fmessage-length=0 -o "tests\\so_main.o" "..\\tests\\so_main.cpp"
g++ -static-libgcc -static-libstdc++ -Xlinker --enable-auto-import -o client.exe "tests\\so_main.o" -lboost_system-mgw45-mt-1_55 -lws2_32