Skip to content

Commit

Permalink
fix __cxa_exception alignment under libstdc++ with gcc
Browse files Browse the repository at this point in the history
Summary:
Fixes: facebook#2359.

In the debugger, I observed calls to `__cxa_allocate_exception` with size `n` calling `malloc` with size `128 + n`. I compared 128 with `sizeof(__cxa_refcounted_exception)` in our replica, which was only 120. So there must have been some difference between the replica and the original. But there was no difference between the fields in `__cxa_refcounted_exception` or in `__cxa_exception`; so the only remaining place to look was in `_Unwind_Exception`. We do not have a replica of `_Unwind_Exception` since `unwind.h` is always available, but it might be from either libgcc or from libunwind, so the difference must have been between these two.

* The type `_Unwind_Exception` is marked in libgcc as being fully aligned: https://github.com/gcc-mirror/gcc/blob/releases/gcc-14.2.0/libgcc/unwind-generic.h#L106.
* Likewise in llvm-unwind: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.7/libunwind/include/unwind_itanium.h#L41.
* It is used without explicit alignment in libstdc++ authoritative `__cxa_exception`: https://github.com/gcc-mirror/gcc/blob/releases/gcc-14.2.0/libstdc%2B%2B-v3/libsupc%2B%2B/unwind-cxx.h#L97.
* The type may not be marked as being fully aligned in upstream libunwind: https://github.com/libunwind/libunwind/blob/v1.8.1/include/unwind.h#L80.
* In our replica of `__cxa_exception`, we must mark the field as being fully aligned in case the replica uses a definition of the type which is not marked as being fully aligned.

Differential Revision: D68391229
  • Loading branch information
yfeldblum authored and facebook-github-bot committed Jan 20, 2025
1 parent f1c1542 commit ff20d64
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion folly/lang/Exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));

namespace __cxxabiv1 {

// libsupc++ itanium-abi __cxa_exception assumes that _Unwind_Exception is
// maximally-aligned, and indeed libgcc itanium-abi _Unwind_Exception is so;
// but libunwind itanium-abi _Unwind_Exception is not maximally-aligned
#ifdef __ARM_EABI_UNWINDER__
// https://github.com/gcc-mirror/gcc/blob/releases/gcc-14.2.0/gcc/ginclude/unwind-arm-common.h#L119
static constexpr size_t __folly_unwind_exception_align = 8;
#else
// https://github.com/gcc-mirror/gcc/blob/releases/gcc-14.2.0/libgcc/unwind-generic.h#L106
static constexpr size_t __folly_unwind_exception_align = alignof(max_align_t);
#endif

static constexpr uint64_t __gxx_primary_exception_class =
0x474E5543432B2B00; // GNCUC++\0
static constexpr uint64_t __gxx_dependent_exception_class =
Expand All @@ -118,7 +129,7 @@ struct __cxa_exception {
_Unwind_Ptr catchTemp;
void* adjustedPtr;
#endif
_Unwind_Exception unwindHeader;
alignas(__folly_unwind_exception_align) _Unwind_Exception unwindHeader;
};

struct __cxa_refcounted_exception {
Expand Down

0 comments on commit ff20d64

Please sign in to comment.