diff --git a/core/core_globals.h b/core/core_globals.h index a5aae961c6..fa095dafa6 100644 --- a/core/core_globals.h +++ b/core/core_globals.h @@ -38,4 +38,5 @@ public: static inline bool leak_reporting_enabled = true; static inline bool print_line_enabled = true; static inline bool print_error_enabled = true; + static inline bool print_ready = false; }; diff --git a/core/error/error_macros.cpp b/core/error/error_macros.cpp index 82e8376bcd..986285181f 100644 --- a/core/error/error_macros.cpp +++ b/core/error/error_macros.cpp @@ -30,6 +30,7 @@ #include "error_macros.h" +#include "core/core_globals.h" #include "core/io/logger.h" #include "core/object/object_id.h" #include "core/object/script_language.h" @@ -106,6 +107,12 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co // Main error printing function. void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, ErrorHandlerType p_type) { + if (!CoreGlobals::print_ready) { + const char *err_details = (p_message && *p_message) ? p_message : p_error; + _err_print_fallback(p_function, p_file, p_line, err_details, p_type, false); + return; + } + if (is_printing_error) { // Fallback if we're already printing an error, to prevent infinite recursion. const char *err_details = (p_message && *p_message) ? p_message : p_error; @@ -142,6 +149,11 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co void _err_print_error_asap(const String &p_error, ErrorHandlerType p_type) { const char *err_details = p_error.utf8().get_data(); + if (!CoreGlobals::print_ready) { + _err_print_fallback(nullptr, nullptr, 0, err_details, p_type, false); + return; + } + if (is_printing_error) { // Fallback if we're already printing an error, to prevent infinite recursion. _err_print_fallback(nullptr, nullptr, 0, err_details, p_type, true); diff --git a/core/string/print_string.cpp b/core/string/print_string.cpp index e669cf7c7d..bae0e26e17 100644 --- a/core/string/print_string.cpp +++ b/core/string/print_string.cpp @@ -38,8 +38,12 @@ static PrintHandlerList *print_handler_list = nullptr; static thread_local bool is_printing = false; -static void __print_fallback(const String &p_string, bool p_err) { - fprintf(p_err ? stderr : stdout, "While attempting to print a message, another message was printed:\n%s\n", p_string.utf8().get_data()); +static void __print_fallback(const String &p_string, bool p_err, bool p_reentrance) { + if (p_reentrance) { + fprintf(p_err ? stderr : stdout, "While attempting to print an error, another error was printed:\n"); + } + + fprintf(p_err ? stderr : stdout, "%s\n", p_string.utf8().get_data()); } void add_print_handler(PrintHandlerList *p_handler) { @@ -78,8 +82,13 @@ void __print_line(const String &p_string) { return; } + if (!CoreGlobals::print_ready) { + __print_fallback(p_string, false, false); + return; + } + if (is_printing) { - __print_fallback(p_string, false); + __print_fallback(p_string, false, true); return; } @@ -279,8 +288,13 @@ void __print_line_rich(const String &p_string) { } output += "\u001b[0m"; // Reset. + if (!CoreGlobals::print_ready) { + __print_fallback(output, false, false); + return; + } + if (is_printing) { - __print_fallback(output, false); + __print_fallback(output, false, true); return; } @@ -301,8 +315,13 @@ void __print_line_rich(const String &p_string) { } void print_raw(const String &p_string) { + if (!CoreGlobals::print_ready) { + __print_fallback(p_string, false, false); + return; + } + if (is_printing) { - __print_fallback(p_string, true); + __print_fallback(p_string, true, true); return; } @@ -318,8 +337,13 @@ void print_error(const String &p_string) { return; } + if (!CoreGlobals::print_ready) { + __print_fallback(p_string, false, false); + return; + } + if (is_printing) { - __print_fallback(p_string, true); + __print_fallback(p_string, true, true); return; } diff --git a/main/main.cpp b/main/main.cpp index 760ba81f12..97f88117fd 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -744,6 +744,8 @@ Error Main::test_setup() { OS::get_singleton()->initialize(); + CoreGlobals::print_ready = true; + engine = memnew(Engine); register_core_types(); @@ -870,6 +872,9 @@ Error Main::test_setup() { void Main::test_cleanup() { ERR_FAIL_COND(!_start_success); + // Printing in the usual way can become problematic during/after cleanup. + CoreGlobals::print_ready = false; + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { TextServerManager::get_singleton()->get_interface(i)->cleanup(); } @@ -1006,6 +1011,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->initialize(); + CoreGlobals::print_ready = true; + #if !defined(OVERRIDE_PATH_ENABLED) && !defined(TOOLS_ENABLED) String old_cwd = OS::get_singleton()->get_cwd(); #if defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED) @@ -5167,6 +5174,9 @@ void Main::cleanup(bool p_force) { ERR_FAIL_COND(!_start_success); } + // Printing in the usual way can become problematic during/after cleanup. + CoreGlobals::print_ready = false; + #ifdef DEBUG_ENABLED if (input) { input->flush_frame_parsed_events();