Blob


1 .TH MACH-STACK 3
2 .SH NAME
3 stacktrace,
4 localaddr,
5 .SH SYNOPSIS
6 .B #include <u.h>
7 .br
8 .B #include <libc.h>
9 .br
10 .B #include <mach.h>
11 .PP
12 .ft B
13 .ta \w'\fBxxxxxx'u +\w'\fBxxxxxx'u
14 int stacktrace(Map *map, Rgetter rget, Tracer trace)
15 .PP
16 .ft B
17 int localvar(Map *map, char *fn, char *val, Loc *loc)
18 .SH DESCRIPTION
19 .I Stacktrace
20 provides machine-independent
21 implementations of process stack traces.
22 They must retrieve data and register contents from an executing
23 image. Sometimes the desired registers are not the current
24 registers but rather a set of saved registers stored elsewhere
25 in memory.
26 The caller may specify an initial register set in the form of an
27 .I Rgetter
28 function, of the form
29 .PP
30 .RS
31 .B "ulong rget(Map *map, char *name)
32 .RE
33 .PP
34 It returns the contents of a register when given a map
35 and a register name.
36 It is usually sufficient for the register function
37 to return meaningful values only for
38 .BR SP
39 and
40 .BR PC ,
41 and for the link register
42 (usually
43 .BR LR )
44 on CISC machines.
45 .PP
46 Given the map and the rgetter,
47 .I stacktrace
48 unwinds the stack starting at the innermost function.
49 At each level in the trace, it calls the tracer function, which has the form
50 .PP
51 .RS
52 .B "int trace(Map *map, ulong pc, ulong callerpc,
53 .br
54 .B " Rgetter rget, Symbol *s)
55 .RE
56 .PP
57 The tracer is passed the map, the current program counter,
58 the program counter of the caller (zero if the caller is unknown),
59 a new
60 .I rget
61 function, and a symbol
62 (see
63 .IR mach-symbol (3))
64 describing the current function
65 (nil if no symbol is known).
66 The value returned by the tracer
67 controls whether the stack trace continues:
68 a zero or negative return value stops the trace,
69 while a positive return value continues it.
70 .PP
71 The rgetter passed to the tracer is not the rgetter
72 passed to
73 .B stacktrace
74 itself.
75 Instead, it is a function returning the register values
76 at the time of the call, to the extent that they can be
77 reconstructed.
78 The most common use for this rgetter
79 is as an argument to
80 .IR lget4 ,
81 etc., when evaluating the locations of local variables.
82 .PP
83 .I Localvar
84 uses
85 .I stacktrace
86 to walk up the stack looking for the innermost instance of a function named
87 .I fn ;
88 once it finds the function,
89 it looks for the parameter or local variable
90 .IR var ,
91 storing the location of the variable in
92 .IR loc .
93 .SH EXAMPLE
94 The following code writes a simple stack trace to standard output,
95 stopping after at most 20 stack frames.
96 .RS
97 .ft B
98 .nf
99 .ta \w'xxxx'u +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
100 static int
101 trace(Map *map, ulong pc, ulong callerpc,
102 Rgetter rget, Symbol *s, int depth)
104 char buf[512];
105 int i, first;
106 u32int v;
107 Symbol s2;
109 if(sym)
110 print("%s+%lx", s->name, pc - loceval(s->loc));
111 else
112 print("%lux", pc);
113 print("(");
114 first = 0;
115 for(i=0; indexlsym(s, &i, &s2)>=0; i++){
116 if(s.class != CPARAM)
117 continue;
118 if(first++)
119 print(", ");
120 if(lget4(map, rget, s->loc, &v) >= 0)
121 print("%s=%#lux", s->name, (ulong)v);
122 else
123 print("%s=???", s->name);
125 print(") called from ");
126 symoff(buf, sizeof buf, callerpc, CTEXT);
127 print("%s\en", buf);
128 return depth < 20;
131 if(stacktrace(map, nil, trace) <= 0)
132 print("no stack frame\n");
133 .RE
134 .SH SOURCE
135 .B /sys/src/libmach
136 .SH SEE ALSO
137 .IR mach (3)