[Return to Library]  [TOC]  [PREV]  SECT--  [NEXT]  [INDEX] [Help]

7    Procedure Invocations and Call Chains

This chapter discusses the library routines that support procedure call tracing. These routines are used to: The chapter also describes the data structures and procedures that these routines require.


[Return to Library]  [TOC]  [PREV]  SECT--  [NEXT]  [INDEX] [Help]

7.1    Referencing a Procedure Invocation

When a reference to a specific procedure invocation is made at run time, the virtual frame pointer or the real frame pointer for that invocation can be used. The virtual frame pointer of a procedure invocation is the contents of the stack pointer at the entry point of the procedure. The real frame pointer of a procedure is the contents of the stack pointer after the size of the fixed part of the stack frame has been subtracted from the virtual frame pointer.

Note that the virtual frame pointer of an invocation is not the value used by the procedure itself for addressing. The contents of the SP register are modified in the procedure prologue and the resulting real frame pointer value is then sometimes copied into FP (as in the case of a variable size stack frame). The real frame pointer is always used for addressing local storage throughout the remainder of the procedure.

The real frame pointer is not, by itself, sufficient to unambiguously identify all possible procedure invocations. For example, a null frame procedure has the same real frame pointer as its caller because the null frame procedure allocates no stack storage. This ambiguity is of no consequence for the purposes of this calling standard because the real frame pointer value is always used in combination with a program counter value that identifies an instruction within a particular procedure.

The static link used in calling nested procedures in languages such as Pascal and Ada is usually the virtual frame pointer or the real frame pointer value. The choice is implementation-dependent and can vary from language to language and release to release.

The full context of a specific procedure invocation is provided through the use of the sigcontext data structure. The sigcontext structure is defined in the file /usr/include/signal.h.


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

7.2    Providing a Procedure Invocation Context

A thread can obtain its own context by calling a system library function defined as follows:
exc_capture_context (ContextRecord)

Arguments:


ContextRecord  Address of a sigcontext structure into which the procedure context of the caller is written 

A thread can obtain the invocation context of the procedure preceding another procedure context by calling a system library routine defined as follows:
exc_virtual_unwind (FunctionEntry, ContextRecord)

Arguments:


FunctionEntry  Address of the function table entry for the function. If zero, the function table entry is looked up using the PC from ContextRecord
ContextRecord  Address of a sigcontext structure. The given structure is updated to represent the context of the previous (calling) frame. 

Function Value:


InPrologueOrEpilogue  If 1, indicates that the resulting program counter value in the given ContextRecord is within the prologue or the epilogue code of the function. If zero, indicates that the program counter is in the body of the function. 

The exc_virtual_unwind()
procedure takes a sigcontext structure together with its associated procedure descriptor and updates the context to reflect the state of the caller at the point where it made the call.


[Return to Library]  [TOC]  [PREV]  --SECT  SECT--  [NEXT]  [INDEX] [Help]

7.3    Walking the Call Chain

During program execution, it is sometimes necessary to navigate (walk) the call chain. For example, frame-based exception handling requires call chain navigation. Call-chain navigation is possible only in the reverse direction; for example, latest-to-earliest procedure, or top to bottom procedure.

There are two steps for performing call chain navigation:

  1. Build a sigcontext structure when given a program state that contains a register set.

    For the current routine, an initial sigcontext structure can be obtained by calling exc_capture_context().

  2. Repeatedly call exc_virtual_unwind() until the end of the chain is reached.

Compilers are allowed to optimize high-level language procedure calls so that they do not appear in the call chain. For example, inline procedures never appear in the call chain.

No assumptions should be made about the relative positions of any memory used for procedure frame information. There is no guarantee that successive stack frames will always appear at higher addresses.