Hi,
I have a project that runs on Ubuntu 16.04 64bit and uses libunwind as a transitive dependency (it's required by google glog, and zeromq). The problem is that the signal mask of the the application gets trashed with a random mask each time a C++ exception is thrown and caught, (I suspect) caused by libunwind. The following code reliably reproduces the problem on my system:
#include <iostream>
#include "signal.h"
#include "string.h"
int main()
{
// no signals masked at startup
try {
throw std::runtime_error("rsgfdg");
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
// signal mask altered at this point, log it
std::cout << "Masked signals:" << std::endl;
sigset_t oldset;
sigprocmask(SIG_SETMASK, nullptr, &oldset);
for (int i = 1; i < NSIG; i++)
if (sigismember(&oldset, i))
std::cout << i << " " << strsignal(i) << std::endl;
return 0;
}
Compiling and linking:
/usr/bin/c++ -g -std=c++14 -Werror -Wall -Wextra -o testMain.cpp.o -c testMain.cpp
/usr/bin/c++ -g testMain.cpp.o -o test_app -rdynamic -lunwind
When I run the test app it always outputs some signals masked. With valgrind I get this output (among other uninitialized read errors in unwind.so):
==9355== Syscall param rt_sigprocmask(set) points to uninitialised byte(s)
==9355== at 0x4E3DEF6: _Ux86_64_setcontext (in /usr/lib/x86_64-linux-gnu/libunwind.so.8.0.1)
==9355== Address 0xffefff418 is on thread 1's stack
My hypothesis is that the unwind implementation in libunwind.so and libgcc_s.so get mixed up:
- all _Unwind_* functions are provided by libgcc_s (transitively via __cxa_throw and co.) except for _Unwind_Resume
- _Unwind_Resume is the only 'U' type symbol in my executable (listed with nm) gets resolved from libunwind.so
Unfortunately I don't know how to dump the full PLT once resolved by the runtime linker, but putting -lgcc_s on the linker command line before unwind solves my issue.
My first question: is my hypotesis correct or plausible? If so, how am I supposed link against libunwind to avoid such issues? I consider the explicitly putting libgcc_s on the link list a workaround...
Can you help me clarify this?
Regards,
Gyorgy Szekely