HOW TO EASILY SOLVE YOUR QDEL ISSUES
Posted: Sat Aug 29, 2015 7:46 pm
Or, "oh god I am so angry about the fact that nobody told me about this".
So, in a PR I'm currently working on that's completely irrelevant to the discussion at hand, I was running into qdel issues. Despite my best efforts to clean up all the references, I simply couldn't get them all, and things weren't GC'ing right. I couldn't figure it out! So I thought to myself, "Surely there's a way to find references to a given object ingame. After all, del() does it, so I'm sure someone along the way would have coded a debug verb or something else to that effect, right?" After asking in #coderbus, I was told that nobody had made such a verb.
Turns out #coderbus was wrong.
In _compile_options.dm, there lies an option called TESTING. When enabled, TESTING will prevent the game from compiling. Don't worry about that. Once you get around the whole "game doesn't compile" thing (which, once that PR is merged, you won't need to worry about) you get access to a wonderful new object verb: Find References. This verb will loop through world and display all references it finds to your object. This is incredible useful for solving qdel issues, as you know exactly what needs to be cleaned up in Destroy.
I decided to take it a step further.
The PR that I linked above has two new features to aid with qdel debugging. The first is another new object verb, qdel() then Find References. This does exactly what you'd expect; it calls qdel() on the object and then it finds all references remaining. This is great, because it means that Destroy() will have been called before it starts to find references, so the only references you'll find will be the ones preventing the object from qdel'ing gracefully.
If you want to be destroying a bunch of objects at once, perhaps via singulo, you can instead make the object's Destroy() return QDEL_HINT_FINDREFERENCE, a new qdel hint which, if TESTING is enabled, will call Find References before placing the object in the queue. While very laggy, this method is incredibly helpful, as you can see leftover references as they arise and prevent an object from GC'ing gracefully.
By using these methods of finding references, you can make your life far, far easier when dealing with qdel() failures.
So, in a PR I'm currently working on that's completely irrelevant to the discussion at hand, I was running into qdel issues. Despite my best efforts to clean up all the references, I simply couldn't get them all, and things weren't GC'ing right. I couldn't figure it out! So I thought to myself, "Surely there's a way to find references to a given object ingame. After all, del() does it, so I'm sure someone along the way would have coded a debug verb or something else to that effect, right?" After asking in #coderbus, I was told that nobody had made such a verb.
Turns out #coderbus was wrong.
In _compile_options.dm, there lies an option called TESTING. When enabled, TESTING will prevent the game from compiling. Don't worry about that. Once you get around the whole "game doesn't compile" thing (which, once that PR is merged, you won't need to worry about) you get access to a wonderful new object verb: Find References. This verb will loop through world and display all references it finds to your object. This is incredible useful for solving qdel issues, as you know exactly what needs to be cleaned up in Destroy.
I decided to take it a step further.
The PR that I linked above has two new features to aid with qdel debugging. The first is another new object verb, qdel() then Find References. This does exactly what you'd expect; it calls qdel() on the object and then it finds all references remaining. This is great, because it means that Destroy() will have been called before it starts to find references, so the only references you'll find will be the ones preventing the object from qdel'ing gracefully.
If you want to be destroying a bunch of objects at once, perhaps via singulo, you can instead make the object's Destroy() return QDEL_HINT_FINDREFERENCE, a new qdel hint which, if TESTING is enabled, will call Find References before placing the object in the queue. While very laggy, this method is incredibly helpful, as you can see leftover references as they arise and prevent an object from GC'ing gracefully.
By using these methods of finding references, you can make your life far, far easier when dealing with qdel() failures.