diff --git a/code/_compile_options.dm b/code/_compile_options.dm index ee53eb99b8d..507ff81e786 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -8,6 +8,11 @@ #define USE_CUSTOM_ERROR_HANDLER #endif +#if defined(OPENDREAM) && !defined(SPACEMAN_DMM) && !defined(CIBUILDING) +// The code is being compiled for OpenDream, and not just for the CI linting. +#define OPENDREAM_REAL +#endif + #ifdef TESTING #define DATUMVAR_DEBUGGING_MODE @@ -112,7 +117,7 @@ // OpenDream currently doesn't support byondapi, so automatically disable it on OD, // unless CIBUILDING is defined - we still want to lint dreamluau-related code. // Get rid of this whenever it does have support. -#if defined(OPENDREAM) && !defined(SPACEMAN_DMM) && !defined(CIBUILDING) +#ifdef OPENDREAM_REAL #define DISABLE_DREAMLUAU #endif diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 366ad006594..d2912cb7fe1 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -188,10 +188,10 @@ SUBSYSTEM_DEF(statpanels) tracy_dll = TRACY_DLL_PATH tracy_present = fexists(tracy_dll) if(tracy_present) - if(GLOB.tracy_initialized) - mc_data.Insert(2, list(list("byond-tracy:", "Active (reason: [GLOB.tracy_init_reason || "N/A"])"))) - else if(GLOB.tracy_init_error) - mc_data.Insert(2, list(list("byond-tracy:", "Errored ([GLOB.tracy_init_error])"))) + if(Tracy.enabled) + mc_data.Insert(2, list(list("byond-tracy:", "Active (reason: [Tracy.init_reason || "N/A"])"))) + else if(Tracy.error) + mc_data.Insert(2, list(list("byond-tracy:", "Errored ([Tracy.error])"))) else if(fexists(TRACY_ENABLE_PATH)) mc_data.Insert(2, list(list("byond-tracy:", "Queued for next round"))) else diff --git a/code/game/world.dm b/code/game/world.dm index dde76a948a7..f9167fed753 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -7,14 +7,6 @@ #define NO_INIT_PARAMETER "no-init" GLOBAL_VAR(restart_counter) -GLOBAL_VAR(tracy_log) -GLOBAL_PROTECT(tracy_log) -GLOBAL_VAR(tracy_initialized) -GLOBAL_PROTECT(tracy_initialized) -GLOBAL_VAR(tracy_init_error) -GLOBAL_PROTECT(tracy_init_error) -GLOBAL_VAR(tracy_init_reason) -GLOBAL_PROTECT(tracy_init_reason) /** * WORLD INITIALIZATION @@ -74,26 +66,20 @@ GLOBAL_PROTECT(tracy_init_reason) RETURN_TYPE(/datum/controller/master) if(!tracy_initialized) - GLOB.tracy_initialized = FALSE -#ifndef OPENDREAM - if(!tracy_initialized) + Tracy = new #ifdef USE_BYOND_TRACY -#warn USE_BYOND_TRACY is enabled - var/should_init_tracy = TRUE - GLOB.tracy_init_reason = "USE_BYOND_TRACY defined" + if(Tracy.enable("USE_BYOND_TRACY defined")) + Genesis(tracy_initialized = TRUE) + return #else - var/should_init_tracy = FALSE + var/tracy_enable_reason if(USE_TRACY_PARAMETER in params) - should_init_tracy = TRUE - GLOB.tracy_init_reason = "world.params" + tracy_enable_reason = "world.params" if(fexists(TRACY_ENABLE_PATH)) - GLOB.tracy_init_reason ||= "enabled for round" + tracy_enable_reason ||= "enabled for round" SEND_TEXT(world.log, "[TRACY_ENABLE_PATH] exists, initializing byond-tracy!") - should_init_tracy = TRUE fdel(TRACY_ENABLE_PATH) -#endif - if(should_init_tracy) - init_byond_tracy() + if(!isnull(tracy_enable_reason) && Tracy.enable(tracy_enable_reason)) Genesis(tracy_initialized = TRUE) return #endif @@ -105,7 +91,7 @@ GLOBAL_PROTECT(tracy_init_reason) _initialize_log_files("data/logs/config_error.[GUID()].log") // Init the debugger first so we can debug Master - init_debugger() + Debugger = new // Create the logger logger = new @@ -243,8 +229,8 @@ GLOBAL_PROTECT(tracy_init_reason) logger.init_logging() - if(GLOB.tracy_log) - rustg_file_write("[GLOB.tracy_log]", "[GLOB.log_directory]/tracy.loc") + if(Tracy.trace_path) + rustg_file_write("[Tracy.trace_path]", "[GLOB.log_directory]/tracy.loc") var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM", TIMEZONE_UTC) + ".yml") GLOB.changelog_hash = fexists(latest_changelog) ? md5(latest_changelog) : 0 //for telling if the changelog has changed recently @@ -353,30 +339,25 @@ GLOBAL_PROTECT(tracy_init_reason) if(do_hard_reboot) log_world("World hard rebooted at [time_stamp()]") shutdown_logging() // See comment below. - shutdown_byond_tracy() - auxcleanup() + QDEL_NULL(Tracy) + QDEL_NULL(Debugger) TgsEndProcess() return ..() log_world("World rebooted at [time_stamp()]") shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. - shutdown_byond_tracy() - auxcleanup() + QDEL_NULL(Tracy) + QDEL_NULL(Debugger) TgsReboot() // TGS can decide to kill us right here, so it's important to do it last ..() #endif -/world/proc/auxcleanup() - var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") - if (debug_server) - call_ext(debug_server, "auxtools_shutdown")() - /world/Del() - shutdown_byond_tracy() - auxcleanup() + QDEL_NULL(Tracy) + QDEL_NULL(Debugger) . = ..() /world/proc/update_status() @@ -509,39 +490,6 @@ GLOBAL_PROTECT(tracy_init_reason) DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(tick_lag * 100) #endif -/world/proc/init_byond_tracy() - if(!fexists(TRACY_DLL_PATH)) - SEND_TEXT(world.log, "Error initializing byond-tracy: [TRACY_DLL_PATH] not found!") - CRASH("Error initializing byond-tracy: [TRACY_DLL_PATH] not found!") - - var/init_result = call_ext(TRACY_DLL_PATH, "init")("block") - if(length(init_result) != 0 && init_result[1] == ".") // if first character is ., then it returned the output filename - SEND_TEXT(world.log, "byond-tracy initialized (logfile: [init_result])") - GLOB.tracy_initialized = TRUE - return GLOB.tracy_log = init_result - else if(init_result == "already initialized") // not gonna question it. - GLOB.tracy_initialized = TRUE - SEND_TEXT(world.log, "byond-tracy already initialized ([GLOB.tracy_log ? "logfile: [GLOB.tracy_log]" : "no logfile"])") - else if(init_result != "0") - GLOB.tracy_init_error = init_result - SEND_TEXT(world.log, "Error initializing byond-tracy: [init_result]") - CRASH("Error initializing byond-tracy: [init_result]") - else - GLOB.tracy_initialized = TRUE - SEND_TEXT(world.log, "byond-tracy initialized (no logfile)") - -/world/proc/shutdown_byond_tracy() - if(GLOB.tracy_initialized) - SEND_TEXT(world.log, "Shutting down byond-tracy") - GLOB.tracy_initialized = FALSE - call_ext(TRACY_DLL_PATH, "destroy")() - -/world/proc/init_debugger() - var/dll = GetConfig("env", "AUXTOOLS_DEBUG_DLL") - if (dll) - call_ext(dll, "auxtools_init")() - enable_debugging() - /world/Profile(command, type, format) if((command & PROFILE_STOP) || !global.config?.loaded || !CONFIG_GET(flag/forbid_all_profiling)) . = ..() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index f23fbbd8629..98b2c87094e 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -881,29 +881,27 @@ ADMIN_VERB(check_missing_sprites, R_DEBUG, "Debug Worn Item Sprites", "We're can if(!icon_exists(actual_file_name, sprite.icon_state)) to_chat(user, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) -#ifndef OPENDREAM +#ifndef OPENDREAM_REAL ADMIN_VERB(start_tracy, R_DEBUG, "Run Tracy Now", "Start running the byond-tracy profiler immediately", ADMIN_CATEGORY_DEBUG) - if(GLOB.tracy_initialized) + if(Tracy.enabled) to_chat(user, span_warning("byond-tracy is already running!"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) return - else if(GLOB.tracy_init_error) - to_chat(user, span_danger("byond-tracy failed to initialize during an earlier attempt: [GLOB.tracy_init_error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + else if(Tracy.error) + to_chat(user, span_danger("byond-tracy failed to initialize during an earlier attempt: [Tracy.error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) return message_admins(span_adminnotice("[key_name_admin(user)] is trying to start the byond-tracy profiler.")) log_admin("[key_name(user)] is trying to start the byond-tracy profiler.") - GLOB.tracy_initialized = FALSE - GLOB.tracy_init_reason = "[user.ckey]" - world.init_byond_tracy() - if(GLOB.tracy_init_error) - to_chat(user, span_danger("byond-tracy failed to initialize: [GLOB.tracy_init_error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) - message_admins(span_adminnotice("[key_name_admin(user)] tried to start the byond-tracy profiler, but it failed to initialize ([GLOB.tracy_init_error])")) - log_admin("[key_name(user)] tried to start the byond-tracy profiler, but it failed to initialize ([GLOB.tracy_init_error])") + if(!Tracy.enable("[user.ckey]")) + var/error = Tracy.error || "N/A" + to_chat(user, span_danger("byond-tracy failed to initialize: [error]"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) + message_admins(span_adminnotice("[key_name_admin(user)] tried to start the byond-tracy profiler, but it failed to initialize ([error])")) + log_admin("[key_name(user)] tried to start the byond-tracy profiler, but it failed to initialize ([error])") return to_chat(user, span_notice("byond-tracy successfully started!"), avoid_highlighting = TRUE, type = MESSAGE_TYPE_DEBUG, confidential = TRUE) message_admins(span_adminnotice("[key_name_admin(user)] started the byond-tracy profiler.")) log_admin("[key_name(user)] started the byond-tracy profiler.") - if(GLOB.tracy_log) - rustg_file_write("[GLOB.tracy_log]", "[GLOB.log_directory]/tracy.loc") + if(Tracy.trace_path) + rustg_file_write("[Tracy.trace_path]", "[GLOB.log_directory]/tracy.loc") ADMIN_VERB_CUSTOM_EXIST_CHECK(start_tracy) return CONFIG_GET(flag/allow_tracy_start) && fexists(TRACY_DLL_PATH) diff --git a/code/modules/debugging/debugger.dm b/code/modules/debugging/debugger.dm new file mode 100644 index 00000000000..6ae39399591 --- /dev/null +++ b/code/modules/debugging/debugger.dm @@ -0,0 +1,54 @@ +/// The debugger instance. +/// This is a GLOBAL_REAL because it initializes before the MC or GLOB. +/// Really only used to check to see if the debugger is enabled or not, +/// and to separate debugger-related code into its own thing. +GLOBAL_REAL(Debugger, /datum/debugger) + +/datum/debugger + /// Is the debugger enabled? + VAR_FINAL/enabled = FALSE + /// The error text, if initializing the debugger errored. + VAR_FINAL/error + /// The path to the auxtools debug DLL, if it sets. + /// Defaults to the environmental variable AUXTOOLS_DEBUG_DLL. + VAR_FINAL/dll_path + +/datum/debugger/New(dll_path) + if(!isnull(Debugger)) + CRASH("Attempted to initialize /datum/debugger when global.Debugger is already set!") + Debugger = src +#ifndef OPENDREAM_REAL + src.dll_path = dll_path || world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") + enable() +#endif + +/datum/debugger/Destroy() +#ifndef OPENDREAM_REAL + if(enabled) + call_ext(dll_path, "auxtools_shutdown")() +#endif + return ..() + +/// Attempt to enable the debugger. +/datum/debugger/proc/enable() +#ifndef OPENDREAM_REAL + if(enabled) + CRASH("Attempted to enable debugger while its already enabled, somehow.") + if(!dll_path) + return FALSE + var/result = call_ext(dll_path, "auxtools_init")() + if(result != "SUCCESS") + error = result + return FALSE + enable_debugging() + enabled = TRUE + return TRUE +#else + return FALSE +#endif + +/datum/debugger/vv_edit_var(var_name, var_value) + return FALSE // no. + +/datum/debugger/CanProcCall(procname) + return FALSE // double no. diff --git a/code/modules/debugging/tracy.dm b/code/modules/debugging/tracy.dm new file mode 100644 index 00000000000..9840a253fb9 --- /dev/null +++ b/code/modules/debugging/tracy.dm @@ -0,0 +1,64 @@ +/// The byond-tracy instance. +/// This is a GLOBAL_REAL because it is the VERY FIRST THING to initialize, even before the MC or GLOB. +GLOBAL_REAL(Tracy, /datum/tracy) + +/datum/tracy + /// Is byond-tracy enabled and running? + VAR_FINAL/enabled = FALSE + /// The error text, if initializing byond-tracy errored. + VAR_FINAL/error + /// A description of what / who enabled byond-tracy. + VAR_FINAL/init_reason + /// A path to the file containing the output trace, if any. + VAR_FINAL/trace_path + +/datum/tracy/New() + if(!isnull(Tracy)) + CRASH("Attempted to initialize /datum/tracy when global.Tracy is already set!") + Tracy = src + +/datum/tracy/Destroy() +#ifndef OPENDREAM_REAL + if(enabled) + call_ext(TRACY_DLL_PATH, "destroy")() +#endif + return ..() + +/// Tries to initialize byond-tracy. +/datum/tracy/proc/enable(init_reason) +#ifndef OPENDREAM_REAL + if(enabled) + return TRUE + src.init_reason = init_reason + if(!fexists(TRACY_DLL_PATH)) + error = "[TRACY_DLL_PATH] not found" + SEND_TEXT(world.log, "Error initializing byond-tracy: [error]") + return FALSE + + var/init_result = call_ext(TRACY_DLL_PATH, "init")("block") + if(length(init_result) != 0 && init_result[1] == ".") // if first character is ., then it returned the output filename + SEND_TEXT(world.log, "byond-tracy initialized (logfile: [init_result])") + enabled = TRUE + return TRUE + else if(init_result == "already initialized") // not gonna question it. + enabled = TRUE + SEND_TEXT(world.log, "byond-tracy already initialized ([trace_path ? "logfile: [trace_path]" : "no logfile"])") + return TRUE + else if(init_result != "0") + error = init_result + SEND_TEXT(world.log, "Error initializing byond-tracy: [init_result]") + return FALSE + else + enabled = TRUE + SEND_TEXT(world.log, "byond-tracy initialized (no logfile)") + return TRUE +#else + error = "OpenDream not supported" + return FALSE +#endif + +/datum/tracy/vv_edit_var(var_name, var_value) + return FALSE // no. + +/datum/tracy/CanProcCall(procname) + return FALSE // double no. diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 7cdc43317e7..0e9b4b54dbd 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -146,6 +146,8 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) GLOB.current_test.Fail("[main_line]\n[desclines.Join("\n")]", file = E.file, line = E.line) #endif + if(Debugger?.enabled) + to_chat(world, span_alertwarning("[main_line]"), type = MESSAGE_TYPE_DEBUG) // This writes the regular format (unwrapping newlines and inserting timestamps as needed). log_runtime("runtime error: [E.name]\n[E.desc]") diff --git a/tgstation.dme b/tgstation.dme index 6cb0fef25e2..4fd22f28eb7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4082,6 +4082,8 @@ #include "code\modules\deathmatch\deathmatch_mapping.dm" #include "code\modules\deathmatch\deathmatch_maps.dm" #include "code\modules\deathmatch\deathmatch_modifier.dm" +#include "code\modules\debugging\debugger.dm" +#include "code\modules\debugging\tracy.dm" #include "code\modules\detectivework\evidence.dm" #include "code\modules\detectivework\scanner.dm" #include "code\modules\discord\accountlink.dm"