[llvm-bugs] [Bug 30879] New: libunwind on i386: cannot deal with absence of frame pointers, even though libgcc can

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Nov 2 00:08:25 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=30879

            Bug ID: 30879
           Summary: libunwind on i386: cannot deal with absence of frame
                    pointers, even though libgcc can
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: ed at 80386.nl
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

The last couple of days I've been looking into a bug that prevented exception
handling from working on i386, using libunwind. As I am by no means an expert
on exception handling, DWARF, etc. etc. I decided to file a bug report. Is this
the right queue for libunwind bugs?

To reproduce this issue:

1. Install FreeBSD HEAD for i386 (i.e., 32-bits x86), which ships with a recent
version of libunwind by default.
2. Check out LLVM/Clang from source and apply the following patch to Clang:

Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp        (revision 285737)
+++ lib/Driver/Tools.cpp        (working copy)
@@ -3369,7 +3369,7 @@
     break;
   }

-  if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI) {
+  if (1) {
     switch (Triple.getArch()) {
     // Don't use a frame pointer on linux if optimizing for certain targets.
     case llvm::Triple::mips64:

3. Store the following C++ files in a directory:

------- a.cpp -------
#include <stdexcept>
void f() {
 throw std::runtime_error("foo");
}
------- b.cpp -------
#include <stdio.h>
void f();
int main() {
  try {
    f();
  } catch(...) {
    fprintf(stderr, "OKAY\n");
  }
}
-------

4. Compile and run it as follows, where ${CXX} corresponds to the freshly built
copy of clang++:

$ ${CXX} -o bla a.cpp b.cpp
$ ./bla
OKAY

5. Now build it with optimisations enabled. This makes the application crash at
runtime, as -O implies that frame pointers may be omitted.

$ ${CXX} -o bla a.cpp b.cpp -O
$ ./bla
Abort trap

6. Get a copy of a stable release of FreeBSD. These versions make use of GNU's
libgcc to do the unwinding. Repeat the entire procedure and you'll observe that
both binaries can run without crashing.

This issue was originally discovered on CloudABI, which as you can see has
frame pointers disabled by default. The reason why CloudABI has frame pointers
disabled by default is because without this, it is unable to build certain
third party packages that use inline assembly with lots of registers. When
frame pointers are enabled, Clang will crash due to it running out of spare
registers.

It is worth noting that libgcc is capable of doing the unwinding properly,
making me assume that we could potentially do something to get libunwind on
par.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20161102/4d379d73/attachment.html>


More information about the llvm-bugs mailing list