Exception handling support to MINIMAL_RUNTIME#8040
Conversation
dff80e3 to
0e9deb2
Compare
|
Flag-wise, we already have a link-time flag called |
kripken
left a comment
There was a problem hiding this comment.
Looks mostly good, but I think we should use the existing DISABLE_EXCEPTION_CATCHING flag as mentioned, and another minor comment or too.
If we do want another link-time flag, I'm not opposed to that, but tying it to this PR seems risky.
0e9deb2 to
497b65a
Compare
The use of If I have int main()
{
throw 4;
}and I do the above code will compile and run, and the throw will be there, printing Imagine the two lines may be coming from different stages of the build system, or I overloaded this setting onto to be explicit. |
497b65a to
45ca734
Compare
70324cd to
a3e62b3
Compare
|
I see the difference between the flags now. But I don't see the benefit. Can the old flag not reduce the throw into an abort(), and then they are basically the same? |
|
The old |
|
I see, thanks. It seems more natural to have |
|
The PR does latch this onto |
sbc100
left a comment
There was a problem hiding this comment.
I like splitting the exceptions library stuff into its own file and disabling it completely when exceptions are not requested.
Is it worth being more consistent about forcing using to opt into exception handling though? IIUC, at the moment we disable exceptions by default at compile time but allow them by default at link time?
| (['-O2'], 31, [], ['waka'], 226582, 20, 33, 566), # noqa | ||
| (['-O2', '-s', 'EMULATED_FUNCTION_POINTERS=1'], | ||
| 32, [], ['waka'], 226582, 20, 32, 565), # noqa | ||
| 31, [], ['waka'], 226582, 20, 33, 566), # noqa |
There was a problem hiding this comment.
Looks like two functions moved from JS exported functions to native functions here.. At least for wasm backend. Does this make sense? Do you know which functions moved?
There was a problem hiding this comment.
I don't know the details on what changed here, this was done blind against the CI. Updated the code a little, not sure what CI says on this now. The major change is the unpacking of the $EXCEPTIONS object, so more functions are now tracked as JS functions; and the deps info mechanism was revised, not sure which function it is pulling in to these (if I had to guess, it'd be free()) I don't have upstream wasm LLVM installed at the moment to verify though.
There was a problem hiding this comment.
I think this is good: what happened is we have _ZSt18uncaught_exceptionv in library.js, as a hack. With the more proper deps here, we get it from the system library. So an import is replaced by an export.
We should remove _ZSt18uncaught_exceptionv from the new src/library_exceptions.js file, but can leave that to a followup.
|
|
||
| terminate: '__cxa_call_unexpected', | ||
|
|
||
| __gxx_personality_v0__deps: ['_ZSt18uncaught_exceptionv', '__cxa_find_matching_catch'], |
There was a problem hiding this comment.
Where these deps simply wrong?
There was a problem hiding this comment.
They were taking a shortcut, i.e. __gxx_personality_v0 depended on something that depended on something that eventually depended on these. I don't remember any more what the exact chain here was to start with, but adjusted to be more precise.
There was a problem hiding this comment.
Oh wait, now I remember. This is due to limitation of deps tracking, a JS function can't depend on a C++ function, then depend back on JS function, and again to C++ function. This seems to be due to JS->C++ function dependencies being resolved once first, and then all JS->JS dependencies second. This moved over to deps_info.json to help around that limitation. (it can safely be added to both, put it back here to be clearer)
|
Just to be clear, if the symbol dependency system works correctly the exception handling library function will only be included if they are used by the program? And this new link time flag lets you know if any of the code you are linking references any of these symbol, because it generated a link error in such cases. And we are not changing the emscipten default here which is to allow exception thrown at link time by default but disallow throwing at compile time default. Seems reasonable, if a little confusing. |
Correct, the deps system does track through when to emit exceptions related code. Although I am not sure if the current deps chain is 100% accurate. One example is that we have something like this: that is, a no-op function that is marked to depend on exceptions. I am not versed on the details of gxx_personality_v0's semantics, but I notice if I remove those deps, then test suite did not pass, so that is necessary.
That's correct.
That is right. It is important to allow throwing by default, since that will make exceptions raise all the way up, which lets one do a convenient global error handler to track aborts from C++ throws. |
0121fd9 to
7ec178f
Compare
Renamed |
dd32beb to
8f87dd2
Compare
8f87dd2 to
46ac093
Compare
6097aaf to
ec02c5c
Compare
ec02c5c to
62fe6d8
Compare
|
Rebased this PR to latest, not sure if this will pass everything, but let's see how things look on the CI. |
kripken
left a comment
There was a problem hiding this comment.
almost lgtm, but I do have questions about all those _1,2,3,.. etc. functions, that worry me.
| "emscripten_get_preloaded_image_data_from_FILE": ["fileno"], | ||
| "__gxx_personality_v0": ["_ZSt18uncaught_exceptionv", "__cxa_find_matching_catch"], | ||
| "__cxa_find_matching_catch": ["__cxa_is_pointer_type", "__cxa_can_catch"], | ||
| "__cxa_find_matching_catch_0": ["__cxa_is_pointer_type", "__cxa_can_catch"], |
There was a problem hiding this comment.
why are all these 1,2,3 etc. versions needed? and why just 10?
There was a problem hiding this comment.
The change to explicitly list out __cxa_find_matching_catch_<number> is a change to migrate these functions to be defined as JS library functions (in src/library_exceptions.js ), instead of the symbols being defined ad hoc in JS linker (used to be in src/jsifier.js at
Line 103 in ee231b0
There was a problem hiding this comment.
I see, sounds good - if we have a nice error if we need more than 10. What would happen in that case?
There was a problem hiding this comment.
if there are more than 10, there will likely be an undefined symbol error, since the linker cannot find a function that LLVM emitted a dependence to
There was a problem hiding this comment.
I worry that's not super-clear, but if it comes up we can look into improving it I guess.
| ___cxa_decrement_exception_refcount | ||
| ___cxa_end_catch | ||
| ___cxa_find_matching_catch | ||
| ___cxa_find_matching_catch_0 |
There was a problem hiding this comment.
Hmm, I don't really know how the JS exceptions machinery works in dynamic linking across main module and side module - before this PR, what would happen if a side module throws an exception with say 3 arguments, but main module did not have a need to generate ___cxa_find_matching_catch_3 in code?
That is, superficially I get an impression that main module would need to emit all these variants to prepare for all possibilities in the side module?
There was a problem hiding this comment.
Honestly, I think exceptions probably did not work in all cases in dynamic linking, we only have very basic testing for that.
62fe6d8 to
2700a46
Compare
| ___cxa_find_matching_catch_29 | ||
| ___cxa_find_matching_catch_3 | ||
| ___cxa_find_matching_catch_30 | ||
| ___cxa_find_matching_catch_31 |
There was a problem hiding this comment.
why does this go up to 31, if the limit is 10?
There was a problem hiding this comment.
Forgot to update the test - earlier I had it go up to 31, but that was excessive. Updated.
|
lgtm with those last comments addressed. |
…ize it by tearing away the object that does not Closure well
a50025b to
65fd1e1
Compare
* Move exceptions test to its own file * Move exception handling support to its own JS library file, and optimize it by tearing away the object that does not Closure well * Add exceptions support to MINIMAL_RUNTIME. * More exception deps fixes, also fix emscripten-core#8046 * Fix tests * Fix __cxa_find_matching_catch to be found under wasmobj0 build mode * Update review comments * Rename SUPPORT_CPP_THROW_EXCEPTION to DISABLE_EXCEPTION_THROWING * Fix test_emcc_s_typo * Fix tests * Fix JS-JS dependency to uncaught_exception from cxa_begin_catch * Limit __cxa_find_matching_catch to 10 arguments, and update tests * Fix wasm metadce test * Update tests * Update tests
This refactors exception handling support to its own file, breaks up the $EXCEPTIONS object, and adds exceptions support to MINIMAL_RUNTIME.
Also adds tracking that the new
library_exceptions.jsfile will only be linked in if-fno-exceptionsis not used. However-fno-exceptionsis traditionally a compiler flag and not a linker flag, so at link time one should also issue-fno-exceptionsto enforce no exceptions getting in, or add the link time flag-s SUPPORT_CPP_THROW_EXCEPTION=0explicitly. This new flag is convenient when one is linking in multiple libraries and doesn't know if one of them used exceptions or not - with-s SUPPORT_CPP_THROW_EXCEPTION=0the wholelibrary_exceptions.jsfile will be omitted, giving immediate linker errors for any exceptions related symbols.