This bug has had me worried recently. It was first reported in RC1:
http://www.neurohack.com/transcendence/ ... php?t=2426
But with infomaniac50's post and an email from Kris Parker I was able to narrow it down to a single point in the code.
In the Korolov code, when a freighter docks with Korolov, there is code that takes the escorts from the freighters and tells them to guard Korolov. The code is very simple (and made simpler below for readability):
Code: Select all
(enum (sysFindObject aObjDocked "sO:escort") theEscort
(block Nil
(shpCancelOrders theEscort)
(shpOrder theEscort "guard" gSource)
)
)
sysFindObject returns all the ships that are ordered to escort aObjDocked (which is the freighter that just docked). We then enum over that list and tell the escorts to guard gSource (Korolov). Simple as can be.
The symptom that I was getting was that sometimes, under some conditions that I could not reproduce, sysFindObject was returning way more objects than just the ones that were escorting the freighter.
Once that happened, all those ships were ordered to guard Korolov.
But why was sysFindObject failing?
The fact that the problem only happened sometimes and the fact that savefiles never reproduced the problem meant to me that it had to be something in temporary memory (not something that's saved out with objects). Somehow memory was being corrupted.
Memory corruption is the scariest bug there is. There is no telling where it originates. A bug in some part of the code could be corrupting memory in a completely different part. The sympton that you see could be totally unrelated to the root of the problem.
I despaired for a bit, but there there two clues that made me feel better: (1) the bug only happened in sysFindObject--if some other part of the code were corrupting memory, then we would get all sorts of strange crashes. (2) Other uses of sysFindObject were working fine--it was just this particular case that seemed to fail sometimes.
After stepping through the code line by line for a while, I finally found it:
Notice that the criteria in the code above does not have a semi-colon at the end of the word 'escort':
(sysFindObject aObjDocked "sO:escort")
The code that parsed the criteria would correctly parse the word 'escort' but, expecting a semi-colon, would continue parsing the string past the end-string character. Once it got past the end of the string, it started parsing whatever garbage it found until it found another end-string character.
Most of the time, it would find the end-string character quickly and no harm would be done. But sometimes, depending on the state of temporary memory, it would find characters that altered the sense of the query.
In particular, if it found another 'O' character it would assume a new order, and if it couldn't understand the order, it just assumed any order. In other words, the criteria was being changed to find any ship with any order (not just the ones escorting the freighter).
This turned out to be a very serious bug. There were other parts of the game that had omitted the ending semi-colon--though it showed up most in Korolov because the query is run so often.
In RC5, I've fixed the code so that sysFindObject behaves properly. I feel a lot better.