3 stacktrace, localaddr, unwindframe, windindex, windreglocs \- stack traces
12 .ta \w'\fBxxxxxx'u +\w'\fBxxxxxx'u
13 int stacktrace(Map *map, Rgetter rget, Tracer trace)
16 int localaddr(Map *map, Regs *regs, char *fn, char *val, ulong *val)
19 int unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)
22 int windindex(char *regname)
25 Loc* windreglocs(void)
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
34 The caller may specify an initial register set in the form of an
39 .B "ulong rget(Map *map, char *name)
42 It returns the contents of a register when given a map
44 It is usually sufficient for the register function
45 to return meaningful values only for
49 and for the link register
54 Given the map and the rgetter,
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
60 .B "int trace(Map *map, ulong pc, ulong callerpc,
62 .B " Rgetter rget, Symbol *s)
65 The tracer is passed the map, the current program counter,
66 the program counter of the caller (zero if the caller is unknown),
69 function, and a symbol
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.
79 The rgetter passed to the tracer is not the rgetter
83 Instead, it is a function returning the register values
84 at the time of the call, to the extent that they can be
86 The most common use for this rgetter
89 etc., when evaluating the locations of local variables.
94 to walk up the stack looking for the innermost instance of a function named
96 once it finds the function,
97 it looks for the parameter or local variable
99 storing the address of the variable in
103 is the low-level function on which
106 Given the current memory image in
108 and the current register set in
113 with the values of the register set
114 at the time of the call to the function in the current program counter.
116 should be the symbol corresponding to the current function,
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,
132 returns the index of the named register
133 in the winding order.
137 structures corresponding to the winding registers,
138 in the winding order.
140 The following code writes a simple stack trace to standard output,
141 stopping after at most 20 stack frames.
145 .ta \w'xxxx'u +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
147 trace(Map *map, ulong pc, ulong callerpc,
148 Rgetter rget, Symbol *s, int depth)
156 print("%s+%lx", s->name, pc - loceval(s->loc));
161 for(i=0; indexlsym(s, &i, &s2)>=0; i++){
162 if(s.class != CPARAM)
166 if(lget4(map, rget, s->loc, &v) >= 0)
167 print("%s=%#lux", s->name, (ulong)v);
169 print("%s=???", s->name);
171 print(") called from ");
172 symoff(buf, sizeof buf, callerpc, CTEXT);
177 if(stacktrace(map, nil, trace) <= 0)
178 print("no stack frame\n");
185 Need to talk about Regs