-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Add helper function for C++ exception formatting #16343
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
Changes from 24 commits
3cf21a0
2ea06c8
693f677
95ef456
103dca8
cc31016
5ca4f18
aa15cc8
493e22f
c7d1267
0231037
af456b1
e233943
83a1a4a
5e765ab
1235600
a83007e
5f19ef5
86b703b
a773e9b
16f160d
fbcf6da
8ad7932
68c129e
c11d036
9c0b0a6
439c09f
77376ea
8dad972
dcc15f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #include "cxa_exception.h" | ||
| #include "cxxabi.h" | ||
| #include <stdio.h> | ||
| #include <typeinfo> | ||
|
|
||
| #ifdef __USING_EMSCRIPTEN_EXCEPTIONS__ | ||
|
|
||
| extern "C" { | ||
|
|
||
| int __cxa_can_catch(const std::type_info* catchType, | ||
| const std::type_info* excpType, | ||
| void** thrown); | ||
|
|
||
| char* emscripten_format_exception(void* exc_ptr) { | ||
| __cxxabiv1::__cxa_exception* exc_info = | ||
| (__cxxabiv1::__cxa_exception*)exc_ptr - 1; | ||
| std::type_info* exc_type = exc_info->exceptionType; | ||
| const char* exc_name = exc_type->name(); | ||
|
|
||
| int status = 0; | ||
| char* demangled_buf = __cxxabiv1::__cxa_demangle(exc_name, 0, 0, &status); | ||
| if (status == 0 && demangled_buf) { | ||
| exc_name = demangled_buf; | ||
| } | ||
|
|
||
| int can_catch = __cxa_can_catch(&typeid(std::exception), exc_type, &exc_ptr); | ||
| char* result = NULL; | ||
| if (can_catch) { | ||
| const char* exc_what = ((std::exception*)exc_ptr)->what(); | ||
| asprintf(&result, "Cpp Exception %s: %s", exc_name, exc_what); | ||
| } else { | ||
| asprintf(&result, | ||
| "Cpp Exception: The exception is an object of type '%s' at " | ||
| "address %p which does not inherit from std::exception", | ||
| exc_name, | ||
| exc_ptr); | ||
| } | ||
|
|
||
| if (demangled_buf) { | ||
| free(demangled_buf); | ||
| } | ||
| return result; | ||
| } | ||
| } | ||
|
|
||
| #endif // __USING_EMSCRIPTEN_EXCEPTIONS__ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1543,6 +1543,63 @@ def test_exceptions_rethrow_missing(self): | |
| create_file('main.cpp', 'int main() { throw; }') | ||
| self.do_runf('main.cpp', None, assert_returncode=NON_ZERO) | ||
|
|
||
| def test_format_exception(self): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then you can also remove
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't work with wasm-exceptions. I am not sure how to make it work with
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, can you open a bug about that so that we remember to get it fixed. I imagine @aheejin will want it to work for sure.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I opened #16380 which is where I got stuck in the wasm-exceptions case. |
||
| # needs to flush stdio streams | ||
| self.set_setting('EXIT_RUNTIME') | ||
hoodmane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| self.set_setting('EXPORTED_FUNCTIONS', ['_main', '_throw_exc']) | ||
| self.set_setting('FORMAT_EXCEPTION_SUPPORT') | ||
| self.set_setting('DISABLE_EXCEPTION_CATCHING', 0) | ||
| self.maybe_closure() | ||
| src = ''' | ||
| #include <emscripten.h> | ||
| #include <exception> | ||
| #include <stdexcept> | ||
| using namespace std; | ||
|
|
||
| class myexception : public exception { | ||
| virtual const char* what() const throw() { return "My exception happened"; } | ||
| } myex; | ||
|
|
||
| extern "C" void throw_exc(int x) { | ||
hoodmane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (x == 1) { | ||
| throw 1000; | ||
| } | ||
| if (x == 2) { | ||
| throw 'c'; | ||
| } | ||
| if (x == 3) { | ||
| throw runtime_error("abc"); | ||
| } | ||
| if (x == 4) { | ||
| throw myex; | ||
| } | ||
| if (x == 5) { | ||
| throw "abc"; | ||
| } | ||
| } | ||
|
|
||
| int main() { | ||
| EM_ASM({ | ||
| for (let i = 1; i < 6; i++){ | ||
| try { | ||
| Module["_throw_exc"](i); | ||
| } catch(p) { | ||
| console.log(Module["formatException"](p).replace(/0x[0-9a-f]*/, "xxx")); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| ''' | ||
| expected = ''' | ||
| Cpp Exception: The exception is an object of type 'int' at address xxx which does not inherit from std::exception | ||
| Cpp Exception: The exception is an object of type 'char' at address xxx which does not inherit from std::exception | ||
| Cpp Exception std::runtime_error: abc | ||
| Cpp Exception myexception: My exception happened | ||
| Cpp Exception: The exception is an object of type 'char const*' at address xxx which does not inherit from std::exception | ||
| '''.strip() + "\n" | ||
hoodmane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| self.do_run(src, expected) | ||
|
|
||
| @with_both_eh_sjlj | ||
| def test_bad_typeid(self): | ||
| self.do_run(r''' | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.