From 32527cfba3edc73efd9f22713cf62a332765dd3d Mon Sep 17 00:00:00 2001 From: Iajret Creature <122297233+Steals-The-PRs@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:15:40 +0300 Subject: [PATCH] [MIRROR] Adds handy define that enables the most common configuration of reftracking (#2175) (#3053) * Adds handy define that enables the most common configuration of reftracking (#82860) ## About The Pull Request This shit has confused people too many times, let's give them an easy pathway to use reftracking Also split the separate logging bit into its own thing * Adds handy define that enables the most common configuration of reftracking --------- Co-authored-by: NovaBot <154629622+NovaBot13@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> --- .github/guides/HARDDELETES.md | 12 ++++++------ code/__HELPERS/logging/_logging.dm | 2 +- code/_compile_options.dm | 18 ++++++++++++++++++ code/_globalvars/logging.dm | 2 +- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/.github/guides/HARDDELETES.md b/.github/guides/HARDDELETES.md index cdbdb2a126d..6817de0d9b3 100644 --- a/.github/guides/HARDDELETES.md +++ b/.github/guides/HARDDELETES.md @@ -1,6 +1,6 @@ # Hard Deletes -> Garbage collection is pretty gothic when you think about it. +> Garbage collection is pretty gothic when you think about it. > >An object in code is like a ghost, clinging to its former life, and especially to the people it knew. It can only pass on and truly die when it has dealt with its unfinished business. And only when its been forgotten by everyone who ever knew it. If even one other object remembers it, it has a connection to the living world that lets it keep hanging on > @@ -52,7 +52,7 @@ This of course means they can store that location in memory in another object's /proc/someshit(mem_location) var/datum/some_obj = new() - some_obj.reference = mem_location + some_obj.reference = mem_location ``` But what happens when you get rid of the object we're passing around references to? If we just cleared it out from memory, everything that holds a reference to it would suddenly be pointing to nowhere, or worse, something totally different! @@ -135,13 +135,13 @@ If that fails, search the object's typepath, and look and see if anything is hol BYOND currently doesn't have the capability to give us information about where a hard delete is. Fortunately we can search for most all of then ourselves. The procs to perform this search are hidden behind compile time defines, since they'd be way too risky to expose to admin button pressing -If you're having issues solving a harddel and want to perform this check yourself, go to `_compile_options.dm` and uncomment `TESTING`, `REFERENCE_TRACKING`, and `GC_FAILURE_HARD_LOOKUP` +If you're having issues solving a harddel and want to perform this check yourself, go to `_compile_options.dm` and uncomment `REFERENCE_TRACKING_STANDARD`. -You can read more about what each of these do in that file, but the long and short of it is if something would hard delete our code will search for the reference (This will look like your game crashing, just hold out) and print information about anything it finds to the runtime log, which you can find inside the round folder inside `/data/logs/year/month/day` +You can read more about what each of these do in that file, but the long and short of it is if something would hard delete our code will search for the reference (This will look like your game crashing, just hold out) and print information about anything it finds to [log_dir]/harddels.log, which you can find inside the round folder inside `/data/logs/year/month/day` -It'll tell you what object is holding the ref if it's in an object, or what pattern of list transversal was required to find the ref if it's hiding in a list of some sort +It'll tell you what object is holding the ref if it's in an object, or what pattern of list transversal was required to find the ref if it's hiding in a list of some sort, alongside the references remaining. -## Techniques For Fixing Hard Deletes +## Techniques For Fixing Hard Deletes Once you've found the issue, it becomes a matter of making sure the ref is cleared as a part of Destroy(). I'm gonna walk you through a few patterns and discuss how you might go about fixing them diff --git a/code/__HELPERS/logging/_logging.dm b/code/__HELPERS/logging/_logging.dm index 1e8b688efcc..c9d5bb3cfbe 100644 --- a/code/__HELPERS/logging/_logging.dm +++ b/code/__HELPERS/logging/_logging.dm @@ -70,7 +70,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global")) SEND_TEXT(world.log, text) #endif -#if defined(REFERENCE_DOING_IT_LIVE) +#if defined(REFERENCE_TRACKING_LOG_APART) #define log_reftracker(msg) log_harddel("## REF SEARCH [msg]") /proc/log_harddel(text) diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 0d534fac9a3..6056a292ed6 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -34,6 +34,8 @@ #define FIND_REF_NO_CHECK_TICK #endif //ifdef GC_FAILURE_HARD_LOOKUP +// Log references in their own file, rather then in runtimes.log +//#define REFERENCE_TRACKING_LOG_APART #endif //ifdef REFERENCE_TRACKING /* @@ -60,8 +62,24 @@ #define REFERENCE_TRACKING // actually look for refs #define GC_FAILURE_HARD_LOOKUP +// Log references in their own file +#define REFERENCE_TRACKING_LOG_APART #endif // REFERENCE_DOING_IT_LIVE +/// Sets up the reftracker to be used locally, to hunt for hard deletions +/// Errors are logged to [log_dir]/harddels.log +//#define REFERENCE_TRACKING_STANDARD +#ifdef REFERENCE_TRACKING_STANDARD +// compile the backend +#define REFERENCE_TRACKING +// actually look for refs +#define GC_FAILURE_HARD_LOOKUP +// spend ALL our time searching, not just part of it +#define FIND_REF_NO_CHECK_TICK +// Log references in their own file +#define REFERENCE_TRACKING_LOG_APART +#endif // REFERENCE_TRACKING_STANDARD + // If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between // #define UNIT_TESTS diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index d91116cedd1..2f05cedf316 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -33,7 +33,7 @@ GLOBAL_PROTECT(##log_var_name);\ DECLARE_LOG(config_error_log, DONT_START_LOG) DECLARE_LOG(perf_log, DONT_START_LOG) // Declared here but name is set in time_track subsystem -#ifdef REFERENCE_DOING_IT_LIVE +#ifdef REFERENCE_TRACKING_LOG_APART DECLARE_LOG_NAMED(harddel_log, "harddels", START_LOG) #endif