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

Implement a "Recovery Mode" for recovering crashing/hanging projects during initialization

This commit is contained in:
Ricardo Subtil
2024-04-30 21:13:10 +01:00
parent bdf625bd54
commit b77aa473a1
34 changed files with 484 additions and 96 deletions

View File

@@ -199,6 +199,7 @@ static uint64_t quit_after = 0;
static OS::ProcessID editor_pid = 0;
#ifdef TOOLS_ENABLED
static bool found_project = false;
static bool recovery_mode = false;
static bool auto_build_solutions = false;
static String debug_server_uri;
static bool wait_for_import = false;
@@ -551,6 +552,7 @@ void Main::print_help(const char *p_binary) {
#ifdef TOOLS_ENABLED
print_help_option("-e, --editor", "Start the editor instead of running the scene.\n", CLI_OPTION_AVAILABILITY_EDITOR);
print_help_option("-p, --project-manager", "Start the project manager, even if a project is auto-detected.\n", CLI_OPTION_AVAILABILITY_EDITOR);
print_help_option("--recovery-mode", "Start the editor in recovery mode, which disables features that can typically cause startup crashes, such as tool scripts, editor plugins, GDExtension addons, and others.\n", CLI_OPTION_AVAILABILITY_EDITOR);
print_help_option("--debug-server <uri>", "Start the editor debug server (<protocol>://<host/IP>[:port], e.g. tcp://127.0.0.1:6007)\n", CLI_OPTION_AVAILABILITY_EDITOR);
print_help_option("--dap-port <port>", "Use the specified port for the GDScript Debugger Adaptor protocol. Recommended port range [1024, 49151].\n", CLI_OPTION_AVAILABILITY_EDITOR);
#if defined(MODULE_GDSCRIPT_ENABLED) && !defined(GDSCRIPT_NO_LSP)
@@ -1435,6 +1437,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
editor = true;
} else if (arg == "-p" || arg == "--project-manager") { // starts project manager
project_manager = true;
} else if (arg == "--recovery-mode") { // Enables recovery mode.
recovery_mode = true;
} else if (arg == "--debug-server") {
if (N) {
debug_server_uri = N->get();
@@ -1904,6 +1908,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
Engine::get_singleton()->set_editor_hint(true);
Engine::get_singleton()->set_extension_reloading_enabled(true);
// Create initialization lock file to detect crashes during startup.
OS::get_singleton()->create_lock_file();
main_args.push_back("--editor");
if (!init_windowed && !init_fullscreen) {
init_maximized = true;
@@ -1919,6 +1926,15 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (project_manager) {
Engine::get_singleton()->set_project_manager_hint(true);
}
if (recovery_mode) {
if (project_manager || !editor) {
OS::get_singleton()->print("Error: Recovery mode can only be used in the editor. Aborting.\n");
goto error;
}
Engine::get_singleton()->set_recovery_mode_hint(true);
}
#endif
OS::get_singleton()->set_cmdline(execpath, main_args, user_args);
@@ -2706,6 +2722,10 @@ error:
print_help(execpath);
}
if (editor) {
OS::get_singleton()->remove_lock_file();
}
EngineDebugger::deinitialize();
if (performance) {
@@ -3620,6 +3640,8 @@ int Main::start() {
editor = true;
} else if (E->get() == "-p" || E->get() == "--project-manager") {
project_manager = true;
} else if (E->get() == "--recovery-mode") {
recovery_mode = true;
} else if (E->get() == "--install-android-build-template") {
install_android_build_template = true;
#endif // TOOLS_ENABLED
@@ -4213,7 +4235,7 @@ int Main::start() {
#ifdef TOOLS_ENABLED
if (editor) {
if (game_path != String(GLOBAL_GET("application/run/main_scene")) || !editor_node->has_scenes_in_session()) {
if (!recovery_mode && (game_path != String(GLOBAL_GET("application/run/main_scene")) || !editor_node->has_scenes_in_session())) {
Error serr = editor_node->load_scene(local_game_path);
if (serr != OK) {
ERR_PRINT("Failed to load scene");
@@ -4296,6 +4318,10 @@ int Main::start() {
Crypto::load_default_certificates(
EditorSettings::get_singleton()->get_setting("network/tls/editor_tls_certificates").operator String());
}
if (recovery_mode) {
Engine::get_singleton()->set_recovery_mode_hint(true);
}
#endif
}