1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-06 12:20:30 +00:00

Add a new notification to detect crashes on native scripts

This commit is contained in:
Marcelo Fernandez
2018-07-02 16:18:58 -03:00
parent 2dc738ce27
commit deebeb2742
8 changed files with 40 additions and 0 deletions

View File

@@ -58,6 +58,7 @@ void MainLoop::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING); BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED); BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
BIND_CONSTANT(NOTIFICATION_WM_ABOUT); BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
BIND_CONSTANT(NOTIFICATION_CRASH);
}; };
void MainLoop::set_init_script(const Ref<Script> &p_init_script) { void MainLoop::set_init_script(const Ref<Script> &p_init_script) {

View File

@@ -62,6 +62,7 @@ public:
// fixes this issue. // fixes this issue.
NOTIFICATION_TRANSLATION_CHANGED = 90, NOTIFICATION_TRANSLATION_CHANGED = 90,
NOTIFICATION_WM_ABOUT = 91, NOTIFICATION_WM_ABOUT = 91,
NOTIFICATION_CRASH = 92,
}; };
virtual void input_event(const Ref<InputEvent> &p_event); virtual void input_event(const Ref<InputEvent> &p_event);

View File

@@ -697,11 +697,21 @@ Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p
Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
if (E) { if (E) {
godot_variant result; godot_variant result;
#ifdef DEBUG_ENABLED
current_method_call = p_method;
#endif
result = E->get().method.method((godot_object *)owner, result = E->get().method.method((godot_object *)owner,
E->get().method.method_data, E->get().method.method_data,
userdata, userdata,
p_argcount, p_argcount,
(godot_variant **)p_args); (godot_variant **)p_args);
#ifdef DEBUG_ENABLED
current_method_call = "";
#endif
Variant res = *(Variant *)&result; Variant res = *(Variant *)&result;
godot_variant_destroy(&result); godot_variant_destroy(&result);
r_error.error = Variant::CallError::CALL_OK; r_error.error = Variant::CallError::CALL_OK;
@@ -716,6 +726,15 @@ Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p
} }
void NativeScriptInstance::notification(int p_notification) { void NativeScriptInstance::notification(int p_notification) {
#ifdef DEBUG_ENABLED
if (p_notification == MainLoop::NOTIFICATION_CRASH) {
if (current_method_call != StringName("")) {
ERR_PRINTS("NativeScriptInstance detected crash on method: " + current_method_call);
current_method_call = "";
}
}
#endif
Variant value = p_notification; Variant value = p_notification;
const Variant *args[1] = { &value }; const Variant *args[1] = { &value };
call_multilevel("_notification", args, 1); call_multilevel("_notification", args, 1);

View File

@@ -181,6 +181,9 @@ class NativeScriptInstance : public ScriptInstance {
Object *owner; Object *owner;
Ref<NativeScript> script; Ref<NativeScript> script;
#ifdef DEBUG_ENABLED
StringName current_method_call;
#endif
void _ml_call_reversed(NativeScriptDesc *script_data, const StringName &p_method, const Variant **p_args, int p_argcount); void _ml_call_reversed(NativeScriptDesc *script_data, const StringName &p_method, const Variant **p_args, int p_argcount);

View File

@@ -78,6 +78,10 @@ static void handle_crash(int sig) {
// Dump the backtrace to stderr with a message to the user // Dump the backtrace to stderr with a message to the user
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str()); fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
char **strings = backtrace_symbols(bt_buffer, size); char **strings = backtrace_symbols(bt_buffer, size);
if (strings) { if (strings) {

View File

@@ -124,6 +124,9 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
fprintf(stderr, "%s: Program crashed\n", __FUNCTION__); fprintf(stderr, "%s: Program crashed\n", __FUNCTION__);
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
// Load the symbols: // Load the symbols:
if (!SymInitialize(process, NULL, false)) if (!SymInitialize(process, NULL, false))
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;

View File

@@ -55,6 +55,10 @@ static void handle_crash(int sig) {
// Dump the backtrace to stderr with a message to the user // Dump the backtrace to stderr with a message to the user
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str()); fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
char **strings = backtrace_symbols(bt_buffer, size); char **strings = backtrace_symbols(bt_buffer, size);
if (strings) { if (strings) {

View File

@@ -656,6 +656,11 @@ void SceneTree::_notification(int p_notification) {
#endif #endif
} break; } break;
case NOTIFICATION_CRASH: {
get_root()->propagate_notification(p_notification);
} break;
default: default:
break; break;
}; };