New MIAMEX function MX_CALLSTACK (189) returns information about the call stack. The motivation here, as with the enhancement to the ST_HOOK_ENV structure, is to allow application routines to identify the context in which they were called. For example, the file hook subroutine, or an error trapping routine, might want to identify not just the location where the file operation or error occurred, but if that location was within a callable routine, the routine(s) that called it. The syntax:
xcall MIAMEX, MX_CALLSTACK, maxdepth, csarray(1) {, program$}
maxdepth (num) [in/out] should be set to the number of elements in the csarray(), i.e. the maximum number of stack levels (working backwards from the current stack frame context) to retrieve. On return, it will be set to the number of levels in the current stack. (If greater than the number you originally specified, it indicates that not all of the levels were returned.)
csarray(1) (array of ST_CALLSTACK) [out] is the first element of an array of structures defined in ASHINC:CALLSTACK.DEF as follows:
defstruct ST_CALLSTACK
map2 calltype,b,2 ! type of call (see CSTF_xxx)
map2 src'lno,b,2 ! line # at or prior to call
map2 src'loc,b,4 ! location counter at call
map2 dst'loc,b,4 ! target location (for call, fn, proc)
map2 dst'name,s,52 ! name of sbx or AMOS command line
endstruct
Typically csarray() would be defined via:
dimx callstack(MAX_CALLSTACK), ST_CALLSTACK
(MAX_CALLSTACK should be set to the maximum # of levels you want to retrieve.)
program$ (string) [out] optionally returns the main program at the top of the callstack.
Example:
++include ashinc:ashell.def
++include ashinc:callstack.bsi
define MAX_CALLSTACK = 10
map1 misc
map2 program$,s,10
map2 stackdepth,i,2
dimx callstack(MAX_CALLSTACK), ST_CALLSTACK
stackdepth = MAX_CALLSTACK ! max # levels we can handle
xcall MIAMEX, MX_CALLSTACK, stackdepth, callstack(1), program$
for i = 1 to stackdepth min MAX_CALLSTACK
? Fn'Call'Stack'Descr$(callstack(i))
next i
The Fn'Call'Stack'Descr$() function referenced above is in the SOSLIB module ASHINC:CALLSTACK.BSI. It creates a one line description of a call (gosub, procedure, function, xcall, amos statement, etc.) from one location/context to another. An example showing a context six levels deep looks like this:
from loc 3B7 call proc() @3DF
from loc 38C fn'() @393
from loc 32B call proc() @331
from loc 4F1 xcall callstack1
from loc 47C fn'() @483
from loc 323 call proc() @41A
Notes
• | In the above example, the program had no line numbers, so they weren't listed in the output. |
• | To match up the location counter values to source code lines, see the LSX file created by the compiler /L switch. |
• | The entry in the array (shown at the top) describes the level that called the code that executed the MX_CALLBACK function. So in the above case, the current code is within a procedure that starts at location 3DF (hex) and was called from location 3B7. Location 3B7 is within a function that starts at location 393, which in turn was called from location 38C, etc. |