<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/56029>56029</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Exceptions not caught in Linux shared library built with libc++
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
bucurb
</td>
</tr>
</table>
<pre>
My team is developing a C++ shared library that is primarily used from C# through P/Invoke. We have noticed a weird behavior with exceptions in the C++ code on Linux, where the following method:
```
extern "C" void test()
{
try
{
throw std::runtime_error("test");
}
catch (std::exception& e)
{
std::cout << "Exception caught: " << e.what() << "\n";
}
catch (...)
{
std::cerr << "Unknown exception caught\n";
}
}
```
does not catch the `std::exception` but instead prints-out `Unknown exception caught` when invoked from C#. The code above works as expected when `test()` is invoked from a C++ unit-test executable that was also built with libc++.
We have since diagnosed the issue to how the `__cxa_allocate_exception` is resolved. Our shared library built with libc++ will reference the `__cxa_allocate_exception` symbol as:
``DF *UND* 0000000000000000 Base __cxa_allocate_exception``
When the C++ unit-test executable loads our shared library, the `__cxa_allocate_exception` is resolved from `libc++abi.so.1` as expected:
``g DF .text 000000000000004b Base __cxa_allocate_exception``
and everything works fine.
However, when our shared library is executed from C#, the process that loads first is actually `dotnet`, which requires:
`` libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f54d1b0b000)``
So, before our library is even loaded, libstdc++ will be loaded and will resolve `__cxa_allocate_exception` to its own implementation:
``g DF .text 000000000000005f CXXABI_1.3 __cxa_allocate_exception``
When our library is finally loaded, the `__cxa_allocate_exception` is already resolved to libstdc++, but presumably some other exception-related symbols are still unresolved, and they are taken from libc++. We therefore end-up with a mix of libc++ and libstdc++ implementations in our shared library, a thing that is not obvious, is unwanted, and probably is also very dangerous in terms of behavior.
The only workaround we have so far is to statically link libc++ into our shared library as well as hide all its symbols, so they are never resolved by the dynamic loader, but it feels very hacky to have to do this. Is there an alternative, cleaner fix?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyVVsmO4zYQ_Rr5QliQZVvtPvjQKzJANiAZZG4NSipZTEukQ1Je_j6vKNuSezqTbkOwFhZrefWqWLkpj-tfjsKTbIVyoqQdNWar9EZI8RCl97iEq6WlUjQqt9JCtpaeZbdWtdKq5ig6h-XKmpa3zCFgTbepxe9R-vxF78wrxeIvErXckdDGqwLSUuxJ2VLkhM_KWLFXvhZ0KGjrldFOKA09dPGhMCUJo8XPSneHKH0Q-5osBZHKNI3Zs8st-dqU0fwuSh6j5C7KktMVXungyWoRpSmUpmJnVIm4nY_SVZTenrbc3PcPAj9vj8PL1UpYRZR74XywN7-znfaqpRey1tigMu2Vp6x8fj_W9Di8FNIXNXxaXRRdMIjSTNDFs3d9uGwqTOdFNH_AxQE-nXVAPzLhIcGfzxIU75HDPu7Rrmj5oPn2_87GcfxRx4DHyMRX_arNXg-JPjv4I9PDw3VCS0OOCXXyi7mAtXeAzBKRAx-lHXheMnG1d9MAWZb8p0vYBZJpbGMKjwgeiz9hKjBS5gak3hv76oR00LGlwkM2bISGEb-gTrlrZUOJdVr5KQtDBRWdl3lDfaHtoVY2ziAC1fi-TFCJRb8xPgET_s815pQuSJRKbrThymRglHMdNBpRg7QnpF5eioN8kageAAjmjvGCq5acaXZUxuK3zr5tAu96g_emwb4KpckufMCOO7a5aYDdULWjVD8-gzR3X399xD9TInnzE-JeOjqT7gd2Lpw5IcXpYe9-nIDGyNIJ81303H8-h2Gfb_biKY1Ws-hueBjgk7mKnYlnvHdEpjf9bMOhApjYo6F9D8oi_zwoUpcCjd8efc1ttKdzpTRd0esns2ehU_PV7-DCEffwjcvljNbWmoKc62ndQ1sp68JZIgvfwccjQ1Qar4nLr7ekUNqW_ukUsHwDhRiDiLo_FwVAzNB0HqP5E_jzjEX8H1bZS7aYNnyATDe66xe-25WukgPjeFMtF-UsT3I89-X7hkN_GPYvp8rgHGIsxiDsgA-HiOxB6MpOXyQ5ndYFg3-qm8CV_2MValh5sBItS7XbhlrSXobFT_FkWYH8377d3X95mcXzTxfPm4BBlpC-IeaP1YdsLDrycagTRHeFVsAYjXoLia5FVR6FMy0Ah3479OyppUYy6_p-AsVIivMMa6fPylkXo42txyDg5StCCUQdtVSeVVh7n1nS5bTb9p1OilYdhKnGLY8VXuf3Oithknm_hUjR19t5oOKjzOSYhjrHy_jS6b3UfvAcJZQHDNTpUOCiFaXUG8LI1Q9NZFvHPp4nq6sa5oPLaCjgGpfYw-Q7HxtGVNKyaiTBsfdFn1OlX8cR4_A07xU_WtaeGu7lolZ8NuKZmXpKCccAExfwNTeTIfH5MVCmPGrZqqInkj1nX3lRESGtId5aFq_HcJax27iXrFa5WHxxfeYAFszzuIcodsRqioakhsFKHaL586Rcz8vb-a2ceOUbWj8Ng2c_UPAEwHCGefNDh9-ks8269n4bulT6jGsDiS6PC9Nys2l259sUefwbvR2v4VwGNs_LLElvJ_U6yQqZp3OSC5nKVSZnRTGbFYvVYpYss2UpJ43MgcQ6WsJoqmnfH-1hfHucqHWapGmSzRazGTrZTZzOkvwmrVazbHGzrLIiWiTUStXE7Eds7GZi18GlvNs4LDbKeTcsSufURhMFc9AvO0zYdp13RWfzSbC8Dp7_C4Uw5i8">