Blame


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