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] |