Why gj :: locate?
You may think it isn’t too difficult to get from label+offset^routine to the actual source line responsible for the error. For an expert it isn't that hard... most of the time. But there are enough oddities and special rules that even an expert can get it wrong, whilst spending a lot of time trying to get there.
gj :: locate is the latest tool from George James Software – it debugs any error, class or routine by converting the location of an error in compiled .int code to the corresponding location in your source, and then taking you right there.
Image this scenario… You’ve got a deadline looming and a mission critical problem in your Greek Alphabet application has been identified with this error code:
set characterCount = characterCount + 1
How do you find the corresponding source code line for this error? There are two ways you could approach it -
For the first, you have to know a few things. Like, you have to know that when a routine ends with a period followed by a number it means it's a class, not a routine. So now you go open up Greek.Alphabet.cls.
Yes, the error message says the problem is in the Greek.Alphabet class, but as you can see, it's empty.
Closer inspection reveals that the source code must have come from one of the superclasses. Greek.Zeta.cls would be a good guess. Let's look in there.
Well, here we are. It's obviously line 10 which is zeta+5. But hang on, the error message was <UNDEFINED> and the undefined variable is characterCount. How can that possibly be? characterCount is clearly being set on the previous line. This error is impossible!
Now you’re feeling a bit challenged, you’re spending longer than you’d like on this – and that deadline getting closer and closer.
Then you remember! Methods are given a z prefix when compiled into an .int routine. Aha! Zeta is the 6th letter of the Greek alphabet, but the 7th letter is Eta. We should be looking for a method called eta.
Let's look at Greek.Eta.cls
Hmm. It's nearly identical to Greek.Zeta.cls and characterCount has clearly been initialised on the previous line. What's going on?
More head scratching, and more checking the clock. Perhaps the problem is something to do with that #include line. Let's look in there.
Line 5 looks promising. But... oh no, characterCount can't be undefined here. It's impossible.
So, eventually, after scolling down 20 or so lines you find some more code:
Now we know why characterCount is undefined, and fortunately it looks like an easy fix. The real error is at line 25 of Greek.Utils.inc. Phew, finally got there.
Remember that second way we mentioned you could approach this? Well, here's how to quickly find the error using gj :: locate -
... and you’ve even got time to make a cuppa before you get back to what you were working on before.
So, this is a somewhat contrived example that spotlights some of the many gotchas you might encounter, however getting from an error message to the corresponding source line can be difficult, especially when you’re working to a pressing deadline.