<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/113534>113534</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
try/catch optimized out under specfic conditions
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
janjaeger
</td>
</tr>
</table>
<pre>
Hi Team,
This is under Debian (trixie) using clang-17 as well as clang-19. Similar for clang-20 (build from git)
We have a situation where we need to intercept certain (synchronous) signals in a signal handler.
We cannot longjmp() out, because that will cause the C++ stack not to be unwound (destructors etc)
So, the only viable solution for us is to throw an exception from the signal handler in those cases, and that works fine in most cases
As the signals are synchronous, we can always guarantee that the state of the stack is what we expect it to be.
However, the try/catch landing pads can in certain cases be optimized out and the throw is not caught.
The below sample illustrates the case.
- we setup a signal handler for a segfault (could also be division by zero or other)
- inside try we cause a segfault
- the signal handler will get control (as expected) and will issue a throw()
- we catch the exception
The below code works with -O0 (or -Xclang -disable-llvm-optzns or -Xclang -disable-llvm-passes)
However with higher levels of optimization the catch will no longer work.
The case works correctly for more complex code (most of what we have), but in the simple cases try/catch gets optimized out.
A work around is to call an external dummy function that is not inline, immediately after try. In that case the optimizer cannot decide to optimize the catch out.
the option -fasync-exceptions looked promising, but appears to be only supported on windows.
Is there any way we can prevent the optimization to optimize landing pads out?
Many thanks,
Jan Jaeger
`
#include <signal.h>
#include <exception>
#include <iostream>
using namespace std;
class signal_exception : public std::exception {
private:
const int signal;
const char * message;
public:
signal_exception(const int sig, const char * msg) : signal(sig), message(msg) {}
signal_exception(const int sig) : signal(sig), message(nullptr) {}
signal_exception(const char * msg) : signal(0), message(msg) {}
signal_exception(const signal_exception &) = default;
const char * what (void) const noexcept {
return message;
}
const int signo(void) const noexcept {
return signal;
}
};
static void segv(void)
{
volatile char *x = nullptr; *x; // cause a segfault
}
static void handler(const int signo)
{
cout << "signal(" << signo << ")\n";
throw(signal_exception(signo, "throw"));
}
int main(int argc, char *argv[], char **envp)
{
signal(SIGSEGV, handler);
cout << "test\n";
try
{
segv();
// volatile char *x = nullptr; *x; // try/catch is always optimized out in this case, even with -O0, ...
}
catch(const signal_exception &e)
{
cout << "exception(" << e.what() << ") signal(" << e.signo() << ")\n";
}
cout << "ended ...\n";
}
`
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV02P4jwS_jXmUgLRDp8HDnT32--HtNrDjHb3tiqcIvG0Y0e2A838-lU5CR0CM9pZLQcI_qh6nqrHVQ6GoAtLtBPLZ7F8nWATS-d339B-QyrITw4uv-z-0PCVsBLyRcxfxXzffn8tdQAdoLE5eXilg0YLQm6i1x-ahNxCE7QtQBm0xfRpDRjgTMbwbze2nQF80ZU26OHofDcs52zm0GiTw9G7CgodhdwOff-ToMQTAULQscGonYVzSZ7gTGCJcogOtI3kFdURFPmIOqELF6tK76xrAkNk-mgCaJts8R8o0eaG_AxGHhVa6yIYZ4tvVS3khg24Jgr5AgdS2ASCWGKEszYG-v8EL0I-C_kMIaJ6BzYRHRwIGnt2jc0ZVU4h-kZF5wNQVCO2Xxy7YFPOmgucNB4MQXCmScQ5ck1KRXQQS-_OgBbog6mneY4h777lx5xj6QITCxTYBdq8Y-D8e4CjtsSrKhdit2iAah8GRgOgJ7gJ7gvnQqEFNGe8BCga9GgjdUFKeyNGAnfs_6h3ZnFOCAjooyYVQXfxmg2dt99_uDOdyPfRif4i5JvCqEowaHNWX415SCi0vcogUeEMuDrqSn-nnNPYsacuhDqkVClsijLeauFrSXAg484QsKoNgTamCdFjpDYm7OAG7pT5BIpNfSezlD6EQMURGxNZDco1Jgc0Ickk1ycdOI-HC3wn78B5cLFk2lvozWsbdJ4i0EadtfdptF_1QARJqwVFUM5G7wz7x9DFnnL2wXFJy3QIDZtNAWr1P6DXxp1dXKX3OGjK5dQp7KxjCdO_pwPvPEz_lSoATHMdWONTY07V1NXxuw0AP1xQY0gC3j7QRuui1EVJHgydyAQWXJf5tnK0KWP0iaZ16YzzXuffZ2MSnNwOvnLek4rmkpJYOU-gHCvioyUp5CadHXe8iprLFiPlmtHE9gxyUpKOWmEOZVxQDLcyvcGzT0AAfSokbQVQyDWWC0Akz6nOm6q6wLGxqmOLsVe3tkZbYjC6qijXGMlcAI-RPMOYAfzZbUisUwnqwPi-HuakkvTcdWoQ0DHg9ru34yxMj8hVY3rVTADj3DvlUHtXae4gfaywrgl96KpnKoWhqWvnI0fGwlnb3J3DDG4O65_pSHoCtBc446WvSrWnE9k45NSpYUDkpopwqc_e4J7O39h0LNG-h1GP_Ast_JU66f0usZp3DzLTVpmGBZO9tOdzVorst0fTn2fr8bx2IXpu1v1024QtVhRqVFxmc5E9D4EogyF0deHfn21DZHuom4PRqt2zF9l-MLvubEDt9Qkj8YJ2oPsoZwMrLHamr15vF6gSPQi5h4pCwIJG4Hhhi-LOwRhxqpwDn6ybsY9QpKqZ7XtQcpNWpgPZI5Cbft36Waxff9Xrf2HfNsbU0f-yj58Smf9faNzrQK5aV6-QU9tO7lP0IJ-p4gm5OTmd2kg7bV1reSCgwcdTbLy9k0I_fWXxM6W5_83nWKSfvtavI8LtN19etAJ2xY329Om233d1dnIGo-YC3wXnI4WzV0H2nMb4F4R8E_LtBx18xP8eR9fVx5rkmNyjUnzpEdmLyF5ASHnVkZCyH057B2vYzPLF8tNIA_2d4IGuOgDJQLcsGZLbTyOPiDH4CjWb4Ef0hUpHuosh-uLUvrYMR4Xckz3Vj_heCX758_cvv_3-D952Ddj2TtSj8EQK8QfcU8fuHm8k1snixnqb31-QRLdjeCvQob9U395g021Ch9SsmR13uOsdiwdms9kn0NFZSqZ_WgboGtURz1GohskfiIlmXBK696YbTcEj7dGsP81368d5eEBmhMjmlCf24wyOhLeaT_Jdlm-zLU5o97SW2_XqScrVpNzNs-0Gj7SarzeLjObbw5GO2WqeLRfZ8rBZyIneyblcPM3lYr59yhar2Xq9zBerDdEyI5RHFIs5VajNjG-tM-eLSbpR756esmW2mBg8kAnpVVxKS-f2vs1ol68Tv0tX3UNTBLGYGx1i-DQTdTS0GyrkVhftK3qoSR214qKY63TVmjTe7MoY68DNNems0LFsDjPlKiHf2EH3M629-0YqCvmWYAUh3zrcp538TwAAAP__x8MJAA">