This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hello. Iâve recently come through an exception uncaught by a correct
corresponding catch block in a binary compiled with clang and gold for
Android. As a result, I suppose the FDE filtering to be added to
discard invalid FDE with 0 PC range to increase compatibility with
ld.bfd. The details are below.
If a function is of a non-void return type and its body is completely
empty, then clang optimizer marks this function as unreachable and
later removes it (if using at least -O1). The FDEs for such removed
functions are not deleted, though, but instead, pc_begin and pc_end
values for these FDEs are adjusted to be the same values, and PC range
of the resulting FDE is 0.
ld.bfd discards 0-range FDEs while reading object files (the code for
it is in the file 'elf-eh-frame.c', function
'_bfd_elf_parse_eh_frame'), while gold includes such entries as-is.
Since these FDEs actually belong to optimized-out functions, there
usually is another valid function starting with the address which is
listed as PC_begin of the 0-range FDE, with its own FDE, containing
valid unwinding information. However, the GCC's unwinder (from
libgcc_s.so) uses only one FDE for a given PC_begin value (since how
can there reasonably be two different FDEs with exactly the same
starting address?), which sometimes happens to be the 0-range FDE
depending on the assembler layout. This FDE cannot be applied to any
address because of its range; the valid FDE for the stack frame is
ignored; the exception is not caught by the corresponding catch clause
and eventually triggers std::terminate.
The root cause of the issue seems to be somewhere in clang; however,
it appears reasonable to add a rather simple fix to gold to improve
its compatibility with ld.bfd, and to improve its robustness.
The original Android test case fixed by the supposed patch is here:
https://android.googlesource.com/platform/ndk/+/master/tests/device/test-stlport_static-exception/jni/dyncast2_1.cpp
To see the issue reproduced, you can compile the attached 'main.cpp'
using ld.gold and ld.bfd and examine the result with 'readelf -wf'. In
the gold-produced binary there will be a potentially faulty entry with
'pc=00000a10..00000a10'.
gold/ChangeLog:
Egor Kochetov <egor.kochetov@intel.com>
* ehframe.h: updated function prototypes to enable discarding
FDEs with 0 PC range
* ehframe.cc: added filtering of FDEs to discard those with 0 PC range.
#include <cstdio>
int f() {}
int g() {
try {
throw "1";
} catch (const char*) {
throw 1;
}
}
int main() {
try {
g();
return 1;
} catch (int) {
printf ("caught int\n");
return 0;
}
return 2;
}
Attachment:
fde-filter.patch
Description: Binary data
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |