Page 1 of 1

Call Stack

Posted: Tue Feb 12, 2019 7:30 am
by gray
If a run-time error occurs, or a user-trap is triggered, is it possible to get (print, or create/retrieve a data structure such as a linked list) the call stack, ie. the chain of procedure calls that resulted in the trap? Thanks.

Re: Call Stack

Posted: Tue Feb 12, 2019 1:08 pm
by cfbsoftware
Currently only the location where the error occurred and the current value of the registers are displayed. Displaying the call stack is on our todo list for a future release. AFAIK It should just require some additional code in the Traps library module.

Re: Call Stack

Posted: Wed Feb 13, 2019 4:22 am
by gray
IMO, that would be a great addition to the debugging toolbox. The location of an error is a good start and mostly helpful for modules of your main controller-logic, but for library modules that are used from different locations, to know what calls lead to an error is crucial. I am also confident that an extension of Traps.mod, unwinding the stack and get the locations of the callers, would be pretty straight forward. I assume that the documentation of the compiler's mechanics for stack management (and related topics, such as the format of the '.ref' resource) is not public, right?

Re: Call Stack

Posted: Wed Feb 13, 2019 11:01 am
by cfbsoftware
Niklaus Wirth describes the compiler's mechanics for stack management in great detail in An Oberon Compiler for the ARM Processor.

The corresponding code generated by the Cortex-M3 code generator of the Astrobe Oberon compiler is effectively the same.

The .ref resource is very straightforward. It is just a resource file with a list of module names and start addresses. The source code of the procedure Traps.GetModname shows how to use the ResData facilties to return the name of the module which contains the code at a specified address. Ideally the debugging reference data would be extended to include procedure names and / or line numbers as well but in the absence of that, the address offsets in the assembly language listings that can be generated in the Professional Edition could be used to help pinpoint the error.

However, we have found the existing simply trap handler to be sufficient to identify most runtime errors in practice, particularly if assertions are used judiciously to validate input parameters to procedures etc. The real tricky problems are the ones that result in infinite loops and never generate a trap. I recall successfully using a watchdog-timer type of technique to diagnose these - I'll see if I can track that down so I can document it here as well.