<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - lld/mac does not create DWARF CU entries for functions that have dwarf entries but not compact unwind entries"
   href="https://bugs.llvm.org/show_bug.cgi?id=50956">50956</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>lld/mac does not create DWARF CU entries for functions that have dwarf entries but not compact unwind entries
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lld
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>MachO
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>nicolasweber@gmx.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>gkm@fb.com, jezreel@gmail.com, llvm-bugs@lists.llvm.org, smeenai@fb.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider this program:


% cat foo.cc
struct A {
  A() {}
  ~A();
};
A::~A() {}
A a;
inline void f() { A a; }
int main() { f(); }


Let's compile it with -fomit-frame-pointer:

% out/gn/bin/clang foo.cc -fomit-frame-pointer -fuse-ld=lld
% xcrun unwinddump a.out
...
[  0] funcOffset=0x00000630, encoding[  1]=0x00000000 __ZN1AD2Ev
[  1] funcOffset=0x00000640, encoding[  0]=0x02020000 __ZN1AD1Ev
[  2] funcOffset=0x00000690, encoding[  1]=0x00000000 __ZN1AC2Ev
[  3] funcOffset=0x000006A0, encoding[  0]=0x02020000 ___cxx_global_var_init



Compare to ld64:

% out/gn/bin/clang foo.cc -fomit-frame-pointer
% xcrun unwinddump a.out
...
[  0] funcOffset=0x00003E70, encoding[  2]=0x04000018 __ZN1AD2Ev
[  1] funcOffset=0x00003E80, encoding[  0]=0x02020000 __ZN1AD1Ev
[  2] funcOffset=0x00003ED0, encoding[  1]=0x04000038 __ZN1AC2Ev
[  3] funcOffset=0x00003EE0, encoding[  0]=0x02020000 ___cxx_global_var_init



So ld64 sees that __ZN1AD2Ev and __ZN1AC2Ev don't have a compact unwind entry,
but they do have an __eh_frame entry, so it synthesizes a 0x04 DWARF CU opcode
for them.


I don't know yet if that actually matters in practice, but we're seeing
libunwind crash on lld-linked binaries, and the code it crashes on is built
with -fomit-frame-pointer and the ld64-linked dylib has a whole bunch of 0x04
encodings.


I wrote a dumb debug info "linker" here
<a href="https://github.com/nico/hack/blob/master/unwinfo.py">https://github.com/nico/hack/blob/master/unwinfo.py</a> that combines symbol names,
compact unwind info and eh_frame. For the foo.o file mentioned above it prints:



% PATH=$PATH:$PWD/out/gn/bin/ ~/src/hack/unwinfo.py foo.o
__ZN1AD2Ev at 0x0
  active EH at 0x0...0x6
  opcodes:
    Format:       DWARF32
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:

    0x0: CFA=RSP+8: RIP=[CFA-8]

__ZN1AD1Ev at 0x10
  active CU: enc 0x02020000 at 0x10...0x20
  EH made inactive by CU at 0x10...0x20
__ZN1AC1Ev at 0x20
  active CU: enc 0x02020000 at 0x20...0x30
  EH made inactive by CU at 0x20...0x30
_main at 0x30
  active CU: enc 0x02020000 at 0x30...0x3a
  EH made inactive by CU at 0x30...0x3a
__Z1fv at 0x40
  active CU: enc 0x02020000 at 0x40...0x53
  EH made inactive by CU at 0x40...0x53
__ZN1AC2Ev at 0x60
  active EH at 0x60...0x66
  opcodes:
    Format:       DWARF32
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:
    DW_CFA_nop:

    0x60: CFA=RSP+8: RIP=[CFA-8]

___cxx_global_var_init at 0x70
  active CU: enc 0x02020000 at 0x70...0x99
  EH made inactive by CU at 0x70...0x99
__GLOBAL__sub_I_foo.cc at 0xa0
  active CU: enc 0x02020000 at 0xa0...0xa8
_a at 0x288


So it kind of seems like an own goal that clang emits EH entries for the
functions in this particular example. It kind of seems like it realizes that no
compact unwind info is needed so it omits it, but that tricks ld64 into
emitting the dwarf CU.

But there might be functions where this actually matters.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>