libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libunwind-devel] Issue with C++ exceptions


From: Kevin Modzelewski
Subject: Re: [Libunwind-devel] Issue with C++ exceptions
Date: Fri, 24 Jun 2016 12:38:45 -0700

I was going to chime in to say we ran into the same thing, and then saw that you linked to our workaround!  We've been running with that fine for some time, though of course we don't need/want the ability to have different signal masks in the same process.  Someone else from our team worked on this, but I think their comment is informative:

/* PYSTON CHANGE: for some reason, libunwind restores the signal mask in _Ux86_64_setcontext() even though _Ux86_64_getcontext doesn't initialize it! This sets our signal mask to random stack garbage, so I've commented it out. - rntz */

I think it was in the realm of "we couldn't understand how it worked for anyone else", but we didn't think to investigate link order issues.

On Fri, Jun 24, 2016 at 6:26 AM, Gyorgy Szekely <address@hidden> wrote:
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...

What's also strange that I didn't find anything about it in the libunwind docs (or the web), but usually when 2 independent libraries provide the same API that's something worth mentioning. The only similar thing I found the web is a forked libunwind repo explicitly commenting out calls to rt_sigprocmask, here: https://lab.nexedi.com/Daetalus/Pyston/commit/1bac7510861a112a9023f821bf3e857a6fb45037#diff-4

Can you help me clarify this?

Regards,
Gyorgy Szekely

_______________________________________________
Libunwind-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/libunwind-devel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]