GSP
Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Support
Contact Us
Online Help
Handbooks
Domain Status
Man Pages

FAQ
Virtual Servers
Pricing
Billing
Technical

Network
Facilities
Connectivity
Topology Map

Miscellaneous
Server Agreement
Year 2038
Credits
 

USA Flag

 

 

Man Pages
MACH-STACK(3) FreeBSD Library Functions Manual MACH-STACK(3)

stacktrace, localaddr, unwindframe, windindex, windreglocs - stack traces

#include <u.h>
#include <libc.h>
#include <mach.h>

int stacktrace(Map *map, Rgetter rget, Tracer trace)

int localaddr(Map *map, Regs *regs, char *fn, char *val, ulong *val)

int unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)

int windindex(char *regname)

Loc* windreglocs(void)

Stacktrace provides machine-independent implementations of process stack traces. They must retrieve data and register contents from an executing image. Sometimes the desired registers are not the current registers but rather a set of saved registers stored elsewhere in memory. The caller may specify an initial register set in the form of an Rgetter function, of the form

ulong rget(Map *map, char *name)

It returns the contents of a register when given a map and a register name. It is usually sufficient for the register function to return meaningful values only for SP and PC, and for the link register (usually LR) on CISC machines.

Given the map and the rgetter, stacktrace unwinds the stack starting at the innermost function. At each level in the trace, it calls the tracer function, which has the form

int trace(Map *map, ulong pc, ulong callerpc,
Rgetter rget, Symbol *s)

The tracer is passed the map, the current program counter, the program counter of the caller (zero if the caller is unknown), a new rget function, and a symbol (see describing the current function (nil if no symbol is known). The value returned by the tracer controls whether the stack trace continues: a zero or negative return value stops the trace, while a positive return value continues it.

The rgetter passed to the tracer is not the rgetter passed to stacktrace itself. Instead, it is a function returning the register values at the time of the call, to the extent that they can be reconstructed. The most common use for this rgetter is as an argument to lget4, etc., when evaluating the locations of local variables.

Localaddr uses stacktrace to walk up the stack looking for the innermost instance of a function named fn ; once it finds the function, it looks for the parameter or local variable var, storing the address of the variable in val.

Unwindframe is the low-level function on which stacktrace is built. Given the current memory image in map and the current register set in regs , unwindframe fills in next with the values of the register set at the time of the call to the function in the current program counter. Sym should be the symbol corresponding to the current function, if available.

The next array holds only the winding registers, typically the caller-save registers and the program counter and stack pointer. The order of registers in the array is called the winding order. The winding set can be found in the array mach->windreg, which has mach->nwindreg entries. Windindex returns the index of the named register in the winding order. Windreglocs returns an array of Loc structures corresponding to the winding registers, in the winding order.

The following code writes a simple stack trace to standard output, stopping after at most 20 stack frames.
static int
trace(Map *map, ulong pc, ulong callerpc,
	Rgetter rget, Symbol *s, int depth)
{
	char buf[512];
	int i, first;
	u32int v;
	Symbol s2;
	if(sym)
		print("%s+%lx", s->name, pc - loceval(s->loc));
	else
		print("%lux", pc);
	print("(");
	first = 0;
	for(i=0; indexlsym(s, &i, &s2)>=0; i++){
		if(s.class != CPARAM)
			continue;
		if(first++)
			print(", ");
		if(lget4(map, rget, s->loc, &v) >= 0)
			print("%s=%#lux", s->name, (ulong)v);
		else
			print("%s=???", s->name);
	}
	print(") called from ");
	symoff(buf, sizeof buf, callerpc, CTEXT);
	print("%s\n", buf);
	return depth < 20;
}
	if(stacktrace(map, nil, trace) <= 0)
		print("no stack frame0);

/src/libmach

Need to talk about Regs

Search for    or go to Top of page |  Section 3 |  Main Index

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with ManDoc.