MIAMEX 189: Get Call Stack Info

Added November 2016

xcall MIAMEX, MX_CALLSTACK, maxdepth, csarray(1) {, program}

MX_CALLSTACK returns information about the call stack. The motivation here 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.

Parameters

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]

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 number 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, subroutine, 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.

History

2016 November, A-Shell 6.3.1538:  Function added to A-Shell.