<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/118276>118276</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Bad exception metadata leads to heap corruption on MSVC ABI, when throwing in a PCH from a member function of an exported class, then copying the exception
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
adalisk-emikhaylov
</td>
</tr>
</table>
<pre>
Just tracked down a nasty bug. Only happens on Windows on MSVC ABI.
When you throw an exception in a PCH, in a member function of a `dllexport`ed class, the metadata for that exception type becomes corrupted: its `CatchableType::copyFunction` becomes null, so whenever the exception has to be copied, [a bitwise copy is performed instead of a deep copy](https://github.com/microsoft/STL/blob/5e0ddadefd38b9ab50f2b8772ad4cb001133fd9d/stl/src/excptptr.cpp#L148).
This in turn leads to heap corruption, e.g. when calling `std::current_exception()`. It should deep-copy the exception into a `shared_ptr`, but instead bitwise copies it, so when the resulting `std::exception_ptr` dies, it brings the *original* exception down with it, which then crashes either when you destroy the original, or when you try to call `std::current_exception()` the second time.
Here's how you reproduce this:
```cpp
// 1.hpp
#include <stdexcept>
struct __declspec(dllexport) A
{
void foo()
{
throw std::runtime_error("Foo!");
}
};
```
```cpp
// 1.cpp
int main()
{
try
{
throw std::runtime_error("Bar!");
}
catch (...)
{
(void)std::current_exception();
}
}
```
Also create an empty `pch.cpp` for the PCH generation.
Run:
```sh
clang-cl /EHsc /MDd /Yc1.hpp /Fp1.pch /FI1.hpp /Fopch.obj -c pch.cpp
clang-cl /EHsc /MDd /Yu1.hpp /Fp1.pch /FI1.hpp /Fo1.obj -c 1.cpp
clang-cl pch.obj 1.obj /link /out:a.exe
.\a.exe
```
Or GNU-style flags: (on Windows, assuming the stock Clang build with MSVC being the default target)
```sh
clang++ -Xclang --dependent-lib=msvcrtd -D_DEBUG -D_DLL -D_MT -o 1pch.gch -xc++-header 1.hpp
clang++ -Xclang --dependent-lib=msvcrtd -D_DEBUG -D_DLL -D_MT 1.cpp -c -o 1.o -include1pch
clang++ -nostartfiles 1.o -o a.exe -v
.\a.exe
```
This shows the following messagebox:
![Image](https://github.com/user-attachments/assets/4ba67092-eaef-4af0-9a7a-9fcbf1975bce)
Removing `__declspec(dllexport)` fixes this.
I'm testing this on Clang 19.1.3. Also reproduces on Clang 18.x.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVktv4zgS_jX0pSBBovw8-OBHezqL7p3FTM_O7imgyJLFCUUKZCmO__2ClOJ4M-j0YjFBYFISWV_VV08Rgj5bxC1b7NniOBMDtc5vhRJGh6cMO_3Uiqtxz7Paqev2b0MgIC_kEypQ7mJBgBWBrlAP5xx-tuYKreh7tAGchd-1Ve6Stl9__ecBdvuHnBU7Vux-b9HC1Q1ArXcXEBbwRWJP2lnQUeo_Dp8ZP4z7DrsaPTSDlemAa0AAWxbKGHzpnSe2LFCBNCKEeIlahA5JKEECGueBWkF3AHTtEWqUrsMA0nk_9ISKVTvQFKLggyDZitrgt2uPrNqxaiddfz1NCrBlcbtuB2MiZnBwadHiM_qE_4bWigDkoEaQrteo4mm22AuoNV10SK-voAP06BvnO1SgbSAUajRUIfbpDFscGV-3RH2IOvET46ezpnaoc-k6xk-dlt4F1xDjp1-_fWH8VBtXM35aYKGUUNioal1vRL0oGl6vVysu1FzWRVGWVdWojWL8FMjEXy8ZP-GL7Kknn8u-Z7z6Us7XjG8mD35rdYjuocFbMChUsrJF0b9SGpniB8D8nCduQApjtD1HhgOpidfBe7T0eOOL8QjClkUODwShdYNRiYMs8fTf3GpLboyF0AqP6rEnz5ZFhK0HuvF4x7TGAJruPJYkegyDofe63XAmsaA0pgDTBLXX9hzSZcZ3zuuztsIwvrvTLiXIRVM7IV5aLdt4xYL0IrQYADW16EdFYjooDOTdaOab0AO4uzPkr5HqyOb_SGUSF1A6q4B0h5MLP6NHxlcBWndJkj323qlBIlCrU5AVu0hn-o9BUExhB2XeTo-VttIMCoFVh0BqBGfVpxEikB8kweOjQmlCj5Lx9Vva8g0kiNWeFTsAgGenFTTOTZqPL98-x7-xYNyM9oONFj2i986na_wU75eM8yiiSnfZ6phwjuPzzaYP7BsftSXohLY3hd6UIX_9PxXcC_9ewSTlOO1kLD_A-DrP8z_RwPg6ssT45oeOfyd6-r2zfWeCA-lREKYS3PV0jSHVyzbZvyym8omxHsMZLXoRAWIA_TLYdxESWlbspBH2nEkDjJ8-fQ4yrl-PKi7_lils4vbUl3mfjDydHt7euojs6j8gk_CqxMcihx-KLF8Flu_FvYKNJxg_GW2f4uoGYtVO5PiCrNjlbHF43d-z97OHn_7-WxboahAaI84xY6J_3jpfTF0RwtDF0pKSkJx8gkPUAOpBGzXWh9Qda3w9pbARgyEg4c9IU-D9mWXG94zvIftXeoIsU9ijVWgpM7pm1bELz9KTguz4ePy0_-2ntPnyJS5fv0HmoIwUnGUL2YscpWUtCoX-luB_BVAiPnogIuYOsqlkRPT3ENYFEp4abTCMhx0k8iF7_sAXqRuFNg4bkcDGGeMukc4OQxBnrN3LFKy8ZIv9QyfO-MN-OgT0mSASsu3QUmD8JELAtJnXYrkqNjxDgU02F02RbcRKZJtG1k25WS1qiZPjit0v2Lnnqbt8txSmbNMvGFLxnUr0A-OrDggDjbGh0zA1xk-5ycu8yiFl8a103x9Y5y9RzkxtK7WpNmKG23JVVWXF58vlrN2WC1xV85Vaznm5XIjleilq1aykxHIuFxJnessLPi95wYvNvCyWeVlvVg3yol5ggwu-ZvMCO6FNbsxzlzt_nukQBtyW5ZqvljMjajQhDZecW7xA-hor3-I489t4KauHc2DzwuhA4U0MaTK43Qt1109vM933xo37QXNsuKm_-zEUXudKaLzrvjNWxjk0-uPdOGnTAPaanjeNZoM32w8CKFozLVnv3R8o42iWOIgxNJH0vOX_CQAA___5-aEC">