-
Notifications
You must be signed in to change notification settings - Fork 50
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
Show original C++ exception stack on ObjC #106
Comments
There is a command line flag "objcpp-disable-exception-translation" to remove the translation. After that you should be able to capture the exception in xcode. |
Thank you for your answer, but I hope that C++ stack information can be displayed in crash stack, not in xcode. So set "objcpp-disable-exception-translation = true" can not achieve my purpose. |
C++ exceptions do not automatically capture their crash stack (unlike ObjC and Java exceptions, which do). So the only way to see where the exception happens is to run the program in a debugger and has the debugger stop on exceptions. This is not a limitation of Djinni, but a C++ thing. |
HACK: in header (e.g: heres an example #ifdef __APPLE___
#include <cxxabi.h>
extern "C" void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*));
#endif in impl: #ifdef __APPLE__
// thrown_exception: Address of thrown exception object
// tinfo: static type of thrown object
// dest: destructor of the exception.
void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) {
if (tinfo) {
int status;
char* real_name = abi::__cxa_demangle(tinfo->name(), 0, 0, &status);
if (status != 0) {
// -1: malloc failed
// -2: mangled_name is not a valid name under the C++ ABI mangling rules.
// -3: one of args is invalid
PrintWarning("Demangling of object type failed - err: '{}'", status);
} else {
PrintWarning("Static type name: '{}'", real_name);
std::string real_name_s{real_name};
// !!All exceptions generated by the standard library inherit from std::exception!!
// so we can safely cast from void* -> std::exception*
const bool can_safely_cast =
real_name_s.find("std::") != std::string::npos ||
// Or one of your own c++ exceptions!
real_name_s.find("SnapChatException::MyCustomSnapChatException") != std::string::npos;
if (can_safely_cast) {
std::exception* e_ptr = static_cast<std::exception*>(thrown_exception);
PrintWarning("std::exception thrown - e.what(): '{}'", e_ptr->what());
}
// Since you can throw any type in C++ (i.e. throw int/char/RandomClass), dont cast
// to anything else and just free.
free(real_name);
}
}
PrintWarning(
"[Custom Exception] Crashing on custom exception -- see stacktrace + logs in your crash reporting tools "
"for info.");
// This is the C++ equivalent of `fatalError()`
__builtin_unreachable();
}
}
#endif This means anytime you Lowkey some bullshit c++ black magic but hey, atleast you have a stack trace |
Thanks @tom-skydio , I have try your advice like bellow, here I use a global variable
However, rewrite __cxa_throw() will hook the global throw event, so it is possible that multiple threads throw at the same time will overwrite the global variable |
you can use a also what's the reasoning behind catching, then rethrowing the exception? that results in the original stack trace being missing, no? [[noreturn]] __attribute__((weak)) void throwNSExceptionFromCurrent(const char * /*ctx*/) {
try {
throw;
}
``` |
I'm trying to disable C++ exception translation in ObjC because I want to see the original C++ stack. However, when the stack is thrown to the ObjC layer, it will be captured by __cxa_throw, and then uniformly converted into the same stack information as bellow:
Is there any way to save the original stack of C++ and display it in the ObjC layer? Thank you very much.
The text was updated successfully, but these errors were encountered: