New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OpenEXR force enabling MSVC exceptions breaks unwinding through C code #1326
Comments
I think that's right, but I'm speculating without a way to try it out. Did you try narrowing it to |
Yes, this commit is the local change to Krita (I plan to push it once I've finished the branch, so commit hash is subject to change). To reproduce it, you need to make it cross at least one DLL boundary. For instance, in this case we have three DLL boundaries:
If libjpeg calls the throwable function, which is done in response to an unrecoverable error, it is possible to make MSVC catch it. However, once told to Continue, the exception will unwind past the stack frames belonging to 3, past 2's catch clause (due to |
Ok, thanks! cc/ @kdt3rd |
According to the Extra CMake Modules documentation [1], > kde_enable_exceptions() > > Enables exceptions for C++ source files compiled for the CMakeLists.txt > file in the current directory and all subdirectories. What isn't listed there, however, is that exceptions are enabled through the usage of -fexceptions (GCC/Clang) and -EHsc (MSVC/Intel) [2]. All good... except that those mean slightly different things: > -fexceptions > > Enable exception handling. Generates extra code needed to propagate > exceptions. For some targets, this implies GCC generates frame > unwind information for all functions, which can produce significant > data size overhead, although it does not affect execution. If you do > not specify this option, GCC enables it by default for languages > like C++ that normally require exception handling, and disables it > for languages like C that do not normally require it. However, you > may need to enable this option when compiling C code that needs to > interoperate properly with exception handlers written in C++. You > may also wish to disable this option if you are compiling older C++ > programs that don’t use exception handling. (source: [3]) > c > When used with /EHs, the compiler assumes that functions declared as > extern "C" never throw a C++ exception. It has no effect when used with > /EHa (that is, /EHca is equivalent to /EHa). /EHc is ignored if /EHs or > /EHa aren't specified. (source: [4]) These two put together mean that any exception thrown in a callstack with C code in between works in Unix-y compilers, while they would crash straight to Qt/QtConcurrent's event loop in MSVC. The only affected piece of code is the JPEG error catcher, introduced by Halla in 5c4c327, so I added a file-level workaround there. A Krita-wide workaround is not possible at the moment; all consumers of kritapigment would need the same surgical workaround, because OpenEXR also injects /EHsc through its exported targets. This was already reported upstream [5]. [1]: https://api.kde.org/ecm/kde-module/KDECompilerSettings.html [2]: https://invent.kde.org/frameworks/extra-cmake-modules/-/blob/v5.101.0/kde-modules/KDECompilerSettings.cmake#L502-526 [3]: https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Code-Gen-Options.html#index-fexceptions [4]: https://learn.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=msvc-170#arguments [5]: AcademySoftwareFoundation/openexr#1326 CCBUG: 361746 CCMAIL: kimageshop@kde.org
Hi,
This bug took me a bit to figure out. Ever since b4d5d86,
/EHsc
is forced upon all consumers of OpenEXR:openexr/cmake/LibraryDefine.cmake
Lines 12 to 14 in 436fcd2
However, there's a possibly unforeseen side effect. While
-fexceptions
allows traversing C code (to the best of my understanding),/EHsc
definitely does not:This subtly broke my attempt to trace an error in Krita's JPEG encoder that went through C code in MSVC, since one of the dependencies of the code publicly inherited OpenEXR's
INTERFACE_COMPILE_OPTIONS
property.I believe a proper fix would be to narrow it to
/EHs
, as that will leave downstream consumers free to disable C code traversal as well, if necessary, otherwise leaving it undisturbed.The text was updated successfully, but these errors were encountered: