plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

mach-stack.3 (4342B)


      1 .TH MACH-STACK 3
      2 .SH NAME
      3 stacktrace, localaddr, unwindframe, windindex, windreglocs \- stack traces
      4 .SH SYNOPSIS
      5 .B #include <u.h>
      6 .br
      7 .B #include <libc.h>
      8 .br
      9 .B #include <mach.h>
     10 .PP
     11 .ft B
     12 .ta \w'\fBxxxxxx'u +\w'\fBxxxxxx'u
     13 int	stacktrace(Map *map, Rgetter rget, Tracer trace)
     14 .PP
     15 .ft B
     16 int	localaddr(Map *map, Regs *regs, char *fn, char *val, ulong *val)
     17 .PP
     18 .ft B
     19 int	unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)
     20 .PP
     21 .ft B
     22 int	windindex(char *regname)
     23 .PP
     24 .ft B
     25 Loc*	windreglocs(void)
     26 .SH DESCRIPTION
     27 .I Stacktrace
     28 provides machine-independent
     29 implementations of process stack traces.
     30 They must retrieve data and register contents from an executing
     31 image.  Sometimes the desired registers are not the current
     32 registers but rather a set of saved registers stored elsewhere
     33 in memory.
     34 The caller may specify an initial register set in the form of an
     35 .I Rgetter
     36 function, of the form
     37 .PP
     38 .RS
     39 .B "ulong rget(Map *map, char *name)
     40 .RE
     41 .PP
     42 It returns the contents of a register when given a map
     43 and a register name.
     44 It is usually sufficient for the register function
     45 to return meaningful values only for 
     46 .BR SP
     47 and
     48 .BR PC ,
     49 and for the link register
     50 (usually
     51 .BR LR )
     52 on CISC machines.
     53 .PP
     54 Given the map and the rgetter,
     55 .I stacktrace
     56 unwinds the stack starting at the innermost function.
     57 At each level in the trace, it calls the tracer function, which has the form
     58 .PP
     59 .RS
     60 .B "int trace(Map *map, ulong pc, ulong callerpc,
     61 .br
     62 .B "	Rgetter rget, Symbol *s)
     63 .RE
     64 .PP
     65 The tracer is passed the map, the current program counter,
     66 the program counter of the caller (zero if the caller is unknown),
     67 a new
     68 .I rget
     69 function, and a symbol 
     70 (see
     71 .MR mach-symbol (3) )
     72 describing the current function
     73 (nil if no symbol is known).
     74 The value returned by the tracer
     75 controls whether the stack trace continues:
     76 a zero or negative return value stops the trace,
     77 while a positive return value continues it.
     78 .PP
     79 The rgetter passed to the tracer is not the rgetter
     80 passed to
     81 .B stacktrace
     82 itself.
     83 Instead, it is a function returning the register values
     84 at the time of the call, to the extent that they can be
     85 reconstructed.
     86 The most common use for this rgetter
     87 is as an argument to
     88 .IR lget4 ,
     89 etc., when evaluating the locations of local variables.
     90 .PP
     91 .I Localaddr
     92 uses
     93 .I stacktrace
     94 to walk up the stack looking for the innermost instance of a function named
     95 .I fn ;
     96 once it finds the function,
     97 it looks for the parameter or local variable
     98 .IR var ,
     99 storing the address of the variable in
    100 .IR val .
    101 .PP
    102 .I Unwindframe
    103 is the low-level function on which
    104 .I stacktrace
    105 is built.
    106 Given the current memory image in
    107 .I map
    108 and the current register set in
    109 .I regs ,
    110 .I unwindframe
    111 fills in
    112 .I next
    113 with the values of the register set 
    114 at the time of the call to the function in the current program counter.
    115 .I Sym
    116 should be the symbol corresponding to the current function,
    117 if available.
    118 .PP
    119 The
    120 .I next
    121 array holds only the
    122 .IR "winding registers" ,
    123 typically the caller-save registers and the program counter and stack pointer.
    124 The order of registers in the array is called the
    125 .IR "winding order" .
    126 The winding set can be found in the array
    127 .IB mach -> windreg \fR,
    128 which has
    129 .IB mach -> nwindreg
    130 entries.
    131 .I Windindex
    132 returns the index of the named register
    133 in the winding order.
    134 .I Windreglocs
    135 returns an array of
    136 .I Loc
    137 structures corresponding to the winding registers,
    138 in the winding order.
    139 .SH EXAMPLE
    140 The following code writes a simple stack trace to standard output,
    141 stopping after at most 20 stack frames.
    142 .RS
    143 .ft B
    144 .nf
    145 .ta \w'xxxx'u +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
    146 static int
    147 trace(Map *map, ulong pc, ulong callerpc,
    148 	Rgetter rget, Symbol *s, int depth)
    149 {
    150 	char buf[512];
    151 	int i, first;
    152 	u32int v;
    153 	Symbol s2;
    154 
    155 	if(sym)
    156 		print("%s+%lx", s->name, pc - loceval(s->loc));
    157 	else
    158 		print("%lux", pc);
    159 	print("(");
    160 	first = 0;
    161 	for(i=0; indexlsym(s, &i, &s2)>=0; i++){
    162 		if(s.class != CPARAM)
    163 			continue;
    164 		if(first++)
    165 			print(", ");
    166 		if(lget4(map, rget, s->loc, &v) >= 0)
    167 			print("%s=%#lux", s->name, (ulong)v);
    168 		else
    169 			print("%s=???", s->name);
    170 	}
    171 	print(") called from ");
    172 	symoff(buf, sizeof buf, callerpc, CTEXT);
    173 	print("%s\en", buf);
    174 	return depth < 20;
    175 }
    176 
    177 	if(stacktrace(map, nil, trace) <= 0)
    178 		print("no stack frame\n");
    179 .RE
    180 .SH SOURCE
    181 .B \*9/src/libmach
    182 .SH SEE ALSO
    183 .MR mach (3)
    184 .SH BUGS
    185 Need to talk about Regs