Date: Sat, 5 Mar 2022 23:33:54 +0100 From: Dimitry Andric <dim@FreeBSD.org> To: Tomoaki AOKI <junchoon@dec.sakura.ne.jp> Cc: John Baldwin <jhb@freebsd.org>, Ed Maste <emaste@freebsd.org>, dev-commits-src-branches@freebsd.org, David Chisnall <theraven@FreeBSD.org> Subject: Re: git: b2127b6f1ae2 - stable/13 - Install unwind.h into /usr/include Message-ID: <682D0394-CDC8-44AB-B9FF-2B969AE2D39A@FreeBSD.org> In-Reply-To: <7482C54A-1128-4AFF-A74E-53D88334C1D9@FreeBSD.org> References: <20220303224535.a0cca57e1f033e930a7f8f9d@dec.sakura.ne.jp> <3166E99F-1616-40D9-BD8B-D18E8104D6FF@FreeBSD.org> <a9863238-04e5-381d-105d-311a2b0c3f56@FreeBSD.org> <6E5AD771-3140-480A-BF20-95B8E8A27189@FreeBSD.org> <20220305113613.7760bb3845cda1c04707fb34@dec.sakura.ne.jp> <7482C54A-1128-4AFF-A74E-53D88334C1D9@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--Apple-Mail=_28BBF4CC-1A41-4611-B0D4-5D22F7DBCFD7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On 5 Mar 2022, at 22:34, Dimitry Andric <dim@FreeBSD.org> wrote: >=20 > On 5 Mar 2022, at 03:36, Tomoaki AOKI <junchoon@dec.sakura.ne.jp> = wrote: ... > So according to the spec, casting the void pointer 'thrown_exception' = to > a __cxa_exception pointer, then subtracting 1, should give you the > original __cxa_exception struct. In this case, it subtracts 8 bytes, > going from 0x87b5aff00 to 0x87b5afe88. Ugh, actually this was 120 bytes! > Now I do exactly the same in the libreoffice frame one below, where = the > incoming void pointer 'pExc' is the previous 'thrown_exception' value: >=20 > (gdb) frame 1 > #1 gcc3::deleteException (pExc=3D0x87b5aff00) at = bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx:139 > 139 OUString unoName( toUNOname( header->exceptionType->name() = ) ); > (gdb) print pExc > $33 =3D (void *) 0x87b5aff00 > (gdb) print static_cast<__cxa_exception*>(pExc)-1 > $34 =3D (__cxa_exception *) 0x87b5afe80 >=20 > So in *this* function, subtracting 1 from a __cxa_exception pointer > subtracts 16 bytes instead, going from 0x87b5aff00 to 0x87b5afe80! And this was 128 bytes instead. I think I now know what's going on, which is that our declaration of __cxa_exception changed its size from 120 bytes to 128 bytes, due to the new unwind headers. Our libcxxrt cxxabi.h header has: struct __cxa_exception { ... lots of stuff ... /** The language-agnostic part of the exception header. */ _Unwind_Exception unwindHeader; }; so the last field is a struct _Unwind_Exception. Our libcxxrt unwind-itanium.h header has: struct _Unwind_Exception { uint64_t exception_class; _Unwind_Exception_Cleanup_Fn exception_cleanup; unsigned long private_1; unsigned long private_2; } ; while libunwind's version has an __aligned__ attribute at the end: struct _Unwind_Exception { uint64_t exception_class; void (*exception_cleanup)(_Unwind_Reason_Code reason, _Unwind_Exception *exc); #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) uintptr_t private_[6]; #else uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use #endif #if __SIZEOF_POINTER__ =3D=3D 4 // The implementation of _Unwind_Exception uses an attribute mode on = the // above fields which has the side effect of causing this whole = struct to // round up to 32 bytes in size (48 with SEH). To be more explicit, = we add // pad fields added for binary compatibility. uint32_t reserved[3]; #endif // The Itanium ABI requires that _Unwind_Exception objects are = "double-word // aligned". GCC has interpreted this to mean "use the maximum = useful // alignment for the target"; so do we. } __attribute__((__aligned__)); (Note that upstream libcxxrt also added the reserved field and aligned attribute, in https://github.com/libcxxrt/libcxxrt/commit/b9616964 !) The aligned attribute on _Unwind_Exception causes the enclosing __cxa_exception struct to *also* be aligned maximally, growing it from 120 to 128 bytes on x86_64. So this is a bit of a fine mess we are in. There are multiple issues here: 1) We broke the ABI by increasing __cxa_exception's size. 2) We compile libcxxrt against its *own* unwind headers, so it assumes a 120-byte __cxa_exception size. But all other programs use the libunwind headers, so they assume a 128 byte __cxa_exception size. I guess LibreOffice is just a good example which breaks because it does this deep poking in exception-handling land, which most programs never go near. That said, LibreOffice also includes the unwind.h header installed by the libunwind-20201110 port, so that is yet *another* possible incompatibility! But I think we must do something about this. The most backward compatible change would be to *remove* the aligned attribute from our _Unwind_Exception declaration, so the old __cxa_exception size is restored. The problem with that is that we have to carry a patch for libunwind forever. The other way would be to force libcxxrt to use the libunwind headers instead of its own, so that at least libcxxrt and libunwind agree on the size and alignment of all these structures! But that may still lead to crashes for older consumers. No easy way out, in any case... :-/ -Dimitry --Apple-Mail=_28BBF4CC-1A41-4611-B0D4-5D22F7DBCFD7 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.2 iF0EARECAB0WIQR6tGLSzjX8bUI5T82wXqMKLiCWowUCYiPlUgAKCRCwXqMKLiCW o2HlAJwLP2bK9/Q29JMrbeIz95neJTf4ggCfUQdNUwOVmgkNcpPGZ/9safz51As= =/Csr -----END PGP SIGNATURE----- --Apple-Mail=_28BBF4CC-1A41-4611-B0D4-5D22F7DBCFD7--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?682D0394-CDC8-44AB-B9FF-2B969AE2D39A>