[Top][All Lists]

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

Re: [Libunwind-devel] libunwind on x86-64 w/ C++ exceptions

From: Mark Rabkin
Subject: Re: [Libunwind-devel] libunwind on x86-64 w/ C++ exceptions
Date: Fri, 15 Feb 2008 16:46:02 -0800
User-agent: Microsoft-Entourage/

In addition, the following tests fail on 'make check' which are _NOT_ expected to fail according to the README (I've filtered out the ones that are expected to fail:

/bin/sh: line 1: 32566 Segmentation fault      ${dir}$tst
FAIL: Gtest-exc
/bin/sh: line 1: 32583 Segmentation fault      ${dir}$tst
FAIL: Ltest-exc

These aren't C++ exceptions, obviously, but is it a similar mechanism?

- Mark

On 2/15/08 4:25 PM, "Mark Rabkin" <address@hidden> wrote:


First, thanks so much for your quick responses -- I really appreciate it.

Thanks for the explanation.   Then, when linking just native libunwind, the following example dies for me as detailed below.  For what it's worth, throwing an exception works for me if there's no objects w/ destructors on the stack, but fails if a class has one.

Linking things I've tried:
- putting libstdc++ explicitly on the command line before and after libunwind doesn't make a difference (but this probably expected since i'm linking libstdc++ as shared).
- linking -lunwind-x86_64 works for both static and shared in isolation for these toy testcases, but gets a lot of unresolved symbol errors when using Google Perf Tools.
- linking both versions (libunwind and libunwind-x86_64) results in the same behavior as if libunwind was linked by itself.

The _Unwind_Resume() symbol I have seems to be the one that comes from libunwind, as intended:

address@hidden /tmp/u]$ nm ./unwind | grep _Unwind_Resume
0000000000400ec0 T _Unwind_Resume
0000000000400ec0 T __libunwind_Unwind_Resume

Example of breakage:
code (unwind.cpp):
struct Foo {
  ~Foo() { }

void throw_int() {
  Foo f;
  throw int(5);

int main(int argc, char** argv) {
  try {
  } catch (...) {
  return 0;

$ ./unwind
$ gdb unwind
Program received signal SIGABRT, Aborted.

#0  0x0000003bd882f3b0 in raise () from /lib64/
#1  0x0000003bd8830860 in abort () from /lib64/
#2  0x0000003bd95bb8c1 in __cxa_get_globals () from /usr/lib64/
#3  0x0000003bd95bb9b4 in __cxa_get_globals () from /usr/lib64/
#4  0x0000003bd95bbd07 in __gxx_personality_v0 ()
   from /usr/lib64/
#5  0x000000000040100b in _Unwind_Resume (exception_object=0x517060)
    at unwind/unwind-internal.h:118
#6  0x0000000000400e84 in throw_int () at unwind.cpp:7
#7  0x0000000000400e98 in main (argc=1, argv=0x7ffffffcb818) at unwind.cpp:12

$ ./unwind-shared

Program received signal SIGSEGV, Segmentation fault.
_x86_64_setcontext () at x86_64/setcontext.S:34
34              fldenv (%r8)

#0  _x86_64_setcontext () at x86_64/setcontext.S:34
#1  0x00002aaaaaab4410 in _ULx86_64_local_resume (as=Variable "as" is not available.
) at x86_64/Gresume.c:74
#2  0x00002aaaaaab44f7 in _ULx86_64_resume (cursor=Variable "cursor" is not available.
) at x86_64/Gresume.c:133
#3  0x00002aaaaaab075f in _Unwind_RaiseException (exception_object=0x501060)
    at unwind/unwind-internal.h:125
#4  0x0000003bd95bc23d in __cxa_throw () from /usr/lib64/
#5  0x00000000004007d6 in throw_int () at unwind.cpp:7
#6  0x0000000000400808 in main (argc=1, argv=0x7ffffff292c8) at unwind.cpp:12

BINS=unwind unwind-shared unwind64 unwind64-shared
all: $(BINS)

unwind: unwind.cpp
        g++ -g -o $@ unwind.cpp /home/mrabkin/unwind/lib/libunwind.a

unwind-shared: unwind.cpp
        g++ -g -o $@ unwind.cpp -L/home/mrabkin/unwind/lib -lunwind

unwind64: unwind.cpp
        g++ -g -o $@ unwind.cpp /home/mrabkin/unwind/lib/libunwind-x86_64.a

unwind64-shared: unwind.cpp
        g++ -g -o $@ unwind.cpp -L/home/mrabkin/unwind/lib -lunwind-x86_64

        rm -f $(BINS)

On 2/15/08 4:09 PM, "Arun Sharma" <address@hidden> wrote:

* libunwind-x86_64.a is needed mainly for cross platform unwinding. If you're unwinding native, you just need libunwind.a

This is explained in libunwind(3) man page.

* libunwind.a and libgcc_eh.a both define _Unwind_Resume(). Which symbol your code sees may vary depending on the order of linking etc. C++ exception handling seemed to break earlier if we link in the one from libunwind.a. I thought my change had fixed that.

This test case works for me after linking with

int main(int argc, char *argv[])
  try {
    throw 20;
  } catch (int i) {
    cout << "caught the exception: " << i << endl;


On Fri, Feb 15, 2008 at 3:35 PM, Mark Rabkin <address@hidden> wrote:
I've done more investigation.

It was barfing on the most trivial of any exception throws when I link "libunwind.a" or "".  However, stack unrolling after exceptions seems to work if I link libunwind-x86_64.{a,so} instead.  What's the exact difference between these two versions of the library?  I can't find any docs that detail it, but I've played around with "nm" and it seems to be a lot of symbol name changes.

Unfortunately, the google perftools seem to want symbols from libunwind that aren't present in libunwind-x86_64 (since the names seem to be different, a lot of changes from UL to U).

Any hints?

- Mark

On 2/15/08 1:30 PM, "Arun Sharma" <address@hidden> wrote:

On Fri, Feb 15, 2008 at 12:27 PM, Mark Rabkin <address@hidden> wrote:
Hi Friendly libunwind Devs,

I'm trying to get libunwind working on my builds on x86-64 (AMD ~2GHz chips), on Linux 2.6 with GCC 4.1.  The reason I'm trying to use libunwind, like probably many others, is to try to use the Google Perf Tools (cpu profiler and TCMalloc).

I'm getting programs dumping core when throwing C++ exceptions and there's objects w/ destructors on the stack that has to be unrolled -- the core dump winds up in ""__gxx_ personality_v0" under "_Unwind_Resume".   I'll provide a small example w/ a stack trace soon.

This is fixed by:;a=commit;h=31440e9796bb34146372df52ed59c4f68ea5839d


Libunwind-devel mailing list

reply via email to

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