PL/SQL doesn't give you nice stack traces when you have an error, I just knew the entry point and the place where the error occurred.
Even knowing the data coming in to the entry point, use of the globals meant that you often couldn't know for sure what route the code would take.
I wrote a primitive PL/SQL parser (in Perl) to turn the call tree into Prolog rules, and then used Prolog to give me the possible routes between the entry point and the error location, making debugging much easier.
Basically the perl pulled a list of scoped function names from the DDL, did a text index on the executable code, and searched the index for references to those functions, creating a list of [from.function, to.function] pairs that I fed into prolog.