<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 - libunwind: After 23bef7ee9923/22b615a96593, backtrace segfault on aarch64 with clang-11 compiled executable"
href="https://bugs.llvm.org/show_bug.cgi?id=50972">50972</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>libunwind: After 23bef7ee9923/22b615a96593, backtrace segfault on aarch64 with clang-11 compiled executable
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Other
</td>
</tr>
<tr>
<th>OS</th>
<td>FreeBSD
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>dimitry@andric.com
</td>
</tr>
<tr>
<th>CC</th>
<td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>As reported in <a href="https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=256864#c13">https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=256864#c13</a>,
after the recent upgrade to LLVM 12.0.1 (including libunwind) in FreeBSD
14.0-CURRENT, some programs using backtrace() on aarch64 started segfaulting,
in particular rust's cargo tool. However, this only occurred for programs built
using the previous version of LLVM, 11.0.1.
E.g., compiling a very small program like:
#include <execinfo.h>
int main() {
void *addrlist[100];
backtrace(addrlist, 100);
}
with clang 11.0.1 on aarch64, then running it on FreeBSD 14.0-CURRENT with
libunwind 12.0.1, will result in a segfault during backtrace(). However, if the
same program is compiled with clang 12.0.1, however, there is no segfault.
The segfault stack trace looks like this:
Program received signal SIGSEGV, Segmentation fault.
libunwind::DwarfInstructions<libunwind::LocalAddressSpace,
libunwind::Registers_arm64>::getSavedRegister (addressSpace=..., registers=...,
cfa=cfa@entry=64, savedReg=...) at
/usr/src/contrib/llvm-project/libunwind/src/DwarfInstructions.hpp:84
84 return (pint_t)addressSpace.getRegister(cfa +
(pint_t)savedReg.value);
(gdb) bt
#0 libunwind::DwarfInstructions<libunwind::LocalAddressSpace,
libunwind::Registers_arm64>::getSavedRegister (addressSpace=..., registers=...,
cfa=cfa@entry=64, savedReg=...) at
/usr/src/contrib/llvm-project/libunwind/src/DwarfInstructions.hpp:84
#1 0x000000004076358c in
libunwind::DwarfInstructions<libunwind::LocalAddressSpace,
libunwind::Registers_arm64>::stepWithDwarf (addressSpace=..., pc=<optimized
out>, fdeStart=<optimized out>, registers=..., isSignalFrame=@0xffffffffe739:
false) at /usr/src/contrib/llvm-project/libunwind/src/DwarfInstructions.hpp:192
#2 0x00000000407630f8 in libunwind::UnwindCursor<libunwind::LocalAddressSpace,
libunwind::Registers_arm64>::stepWithDwarfFDE (this=0xffffffffe4d0) at
/usr/src/contrib/llvm-project/libunwind/src/UnwindCursor.hpp:954
#3 libunwind::UnwindCursor<libunwind::LocalAddressSpace,
libunwind::Registers_arm64>::step (this=0xffffffffe4d0) at
/usr/src/contrib/llvm-project/libunwind/src/UnwindCursor.hpp:2090
#4 0x0000000040760b64 in _Unwind_Backtrace (callback=0x402aecdc <tracer>,
ref=<optimized out>) at
/usr/src/contrib/llvm-project/libunwind/src/UnwindLevel1-gcc-ext.c:131
#5 0x00000000402aec90 in backtrace (arr=<optimized out>, len=<optimized out>)
at /usr/src/contrib/libexecinfo/unwind.c:69
#6 0x00000000002108c0 in main () at bt.c:6
(gdb) print cfa
$1 = 64
(gdb) print savedReg.value
$2 = -8
E.g. getRegister effectively tries to do a get64() on the address 64-8 = 56,
which causes a segfault.
After some bisection, the segfault turned out to be caused by
<a href="https://github.com/llvm/llvm-project/commit/22b615a96593">https://github.com/llvm/llvm-project/commit/22b615a96593</a> ("[libunwind] Support
for leaf function unwinding"), which was a re-land of
<a href="https://github.com/llvm/llvm-project/commit/23bef7ee9923">https://github.com/llvm/llvm-project/commit/23bef7ee9923</a>.
I'm unsure on how to debug this further, as the difference between the
executables's .eh_frame sections is signifcant. The clang 11.0.1 compiled
executable's .eh_frame section decodes to:
The section .eh_frame contains:
0000001c 00000014 00000000 CIE "zR" cf=1 df=-4 ra=30
LOC CFA
0021063c r31+0
00000018 0000001c 0000001c FDE cie=00000000 pc=0021063c..002106d8
LOC CFA r19 r20 r21 r29 ra
0021063c r31+0 u u u u u
0021064c r29+48 c-8 c-16 c-32 c-48 c-40
00000038 00000024 0000003c FDE cie=00000000 pc=002106d8..002107f8
LOC CFA r19 r20 r21 r22 r23 r24 r29 ra
002106d8 r31+0 u u u u u u u u
002106ec r29+64 c-8 c-16 c-24 c-32 c-40 c-48 c-64 c-56
00000060 00000024 00000064 FDE cie=00000000 pc=002107f8..00210858
LOC CFA r19 r20 r29 ra
002107f8 r31+0 u u u u
00210804 r29+32 c-8 c-16 c-32 c-24
00000088 0000001c 0000008c FDE cie=00000000 pc=00210898..002108d8
LOC CFA r28 r29 ra
00210898 r31+0 u u u
002108a8 r29+32 c-16 c-32 c-24
while the clang 12.0.1 compiled executable's .eh_frame section decodes to:
The section .eh_frame contains:
0000001c 00000014 00000000 CIE "zR" cf=1 df=-4 ra=30
LOC CFA
002107dc r31+0
00000018 00000014 0000001c FDE cie=00000000 pc=002107dc..002107f4
LOC CFA
002107dc r31+0
00000030 0000001c 00000034 FDE cie=00000000 pc=00210828..00210864
LOC CFA r28 r29 ra
00210828 r31+0 u u u
00210838 r29+32 c-16 c-32 c-24</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>