blob: d08258bdd622f5596ed2108fe0434b44a0e51da1 [file] [log] [blame]
<head>
<title>mach-stack(3) - Plan 9 from User Space</title>
<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
</head>
<body bgcolor=#ffffff>
<table border=0 cellpadding=0 cellspacing=0 width=100%>
<tr height=10><td>
<tr><td width=20><td>
<tr><td width=20><td><b>MACH-STACK(3)</b><td align=right><b>MACH-STACK(3)</b>
<tr><td width=20><td colspan=2>
<br>
<p><font size=+1><b>NAME </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
stacktrace, localaddr, unwindframe, windindex, windreglocs &ndash; stack
traces<br>
</table>
<p><font size=+1><b>SYNOPSIS </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
<tt><font size=+1>#include &lt;u.h&gt;<br>
#include &lt;libc.h&gt;<br>
#include &lt;mach.h&gt;
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
</font></tt>
int &nbsp;&nbsp;&nbsp;&nbsp;stacktrace(Map *map, Rgetter rget, Tracer trace)
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
int &nbsp;&nbsp;&nbsp;&nbsp;localaddr(Map *map, Regs *regs, char *fn, char *val, ulong
*val)
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
int &nbsp;&nbsp;&nbsp;&nbsp;unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
int &nbsp;&nbsp;&nbsp;&nbsp;windindex(char *regname)
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
Loc* &nbsp;&nbsp;&nbsp;windreglocs(void)<br>
</table>
<p><font size=+1><b>DESCRIPTION </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
<i>Stacktrace</i> 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 <i>Rgetter</i> function, of the form
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
<tt><font size=+1>ulong rget(Map *map, char *name)<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
</font></tt>
</table>
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 <tt><font size=+1>SP</font></tt> and <tt><font size=+1>PC</font></tt>, and for the link register
(usually <tt><font size=+1>LR</font></tt>) on CISC machines.
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
Given the map and the rgetter, <i>stacktrace</i> unwinds the stack starting
at the innermost function. At each level in the trace, it calls
the tracer function, which has the form
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
<tt><font size=+1>int trace(Map *map, ulong pc, ulong callerpc,<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
Rgetter rget, Symbol *s)<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
</table>
</font></tt>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
</table>
</table>
The tracer is passed the map, the current program counter, the
program counter of the caller (zero if the caller is unknown),
a new <i>rget</i> function, and a symbol (see <a href="../man3/mach-symbol.html"><i>mach-symbol</i>(3)</a>) 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.
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
The rgetter passed to the tracer is not the rgetter passed to
<tt><font size=+1>stacktrace</font></tt> 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 <i>lget4</i>, etc., when evaluating the locations of local
variables.
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
<i>Localaddr</i> uses <i>stacktrace</i> to walk up the stack looking for the
innermost instance of a function named <i>fn ;</i> once it finds the
function, it looks for the parameter or local variable <i>var</i>, storing
the address of the variable in <i>val</i>.
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
<i>Unwindframe</i> is the low-level function on which <i>stacktrace</i> is built.
Given the current memory image in <i>map</i> and the current register
set in <i>regs , unwindframe</i> fills in <i>next</i> with the values of the
register set at the time of the call to the function in the current
program counter. <i>Sym</i> should be the symbol corresponding to
the current function, if available.
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
The <i>next</i> array holds only the <i>winding registers</i>, typically the
caller-save registers and the program counter and stack pointer.
The order of registers in the array is called the <i>winding order</i>.
The winding set can be found in the array <i>mach</i><tt><font size=+1>&#8722;&gt;</font></tt><i>windreg</i>, which
has <i>mach</i><tt><font size=+1>&#8722;&gt;</font></tt><i>nwindreg</i> entries. <i>Windindex</i> returns the index of
the named register in the winding order. <i>Windreglocs</i> returns an
array of <i>Loc</i> structures corresponding to the winding registers,
in the winding order.<br>
</table>
<p><font size=+1><b>EXAMPLE </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
The following code writes a simple stack trace to standard output,
stopping after at most 20 stack frames.<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
static int<br>
trace(Map *map, ulong pc, ulong callerpc,<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
Rgetter rget, Symbol *s, int depth)<br>
</table>
{<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
char buf[512];<br>
int i, first;<br>
u32int v;<br>
Symbol s2;<br>
if(sym)<br>
print(&quot;%s+%lx&quot;, s-&gt;name, pc - loceval(s-&gt;loc));<br>
else<br>
print(&quot;%lux&quot;, pc);<br>
print(&quot;(&quot;);<br>
first = 0;<br>
for(i=0; indexlsym(s, &amp;i, &amp;s2)&gt;=0; i++){<br>
if(s.class != CPARAM)<br>
continue;<br>
if(first++)<br>
print(&quot;, &quot;);<br>
if(lget4(map, rget, s-&gt;loc, &amp;v) &gt;= 0)<br>
print(&quot;%s=%#lux&quot;, s-&gt;name, (ulong)v);<br>
else<br>
print(&quot;%s=???&quot;, s-&gt;name);<br>
}<br>
print(&quot;) called from &quot;);<br>
symoff(buf, sizeof buf, callerpc, CTEXT);<br>
print(&quot;%s\n&quot;, buf);<br>
return depth &lt; 20;<br>
</table>
}<br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
if(stacktrace(map, nil, trace) &lt;= 0)<br>
print(&quot;no stack frame0);<br>
</table>
</table>
</table>
<p><font size=+1><b>SOURCE </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
<tt><font size=+1>/usr/local/plan9/src/libmach<br>
</font></tt>
</table>
<p><font size=+1><b>SEE ALSO </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
<a href="../man3/mach.html"><i>mach</i>(3)</a><br>
</table>
<p><font size=+1><b>BUGS </b></font><br>
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
Need to talk about Regs<br>
</table>
<td width=20>
<tr height=20><td>
</table>
<!-- TRAILER -->
<table border=0 cellpadding=0 cellspacing=0 width=100%>
<tr height=15><td width=10><td><td width=10>
<tr><td><td>
<center>
<a href="../../"><img src="../../dist/spaceglenda100.png" alt="Space Glenda" border=1></a>
</center>
</table>
<!-- TRAILER -->
</body></html>