Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
MACH-STACK(3)		   Library Functions Manual		 MACH-STACK(3)

       stacktrace,  localaddr,	unwindframe,  windindex,  windreglocs  - stack

       #include	<u.h>
       #include	<libc.h>
       #include	<mach.h>

       int   stacktrace(Map *map, Rgetter rget,	Tracer trace)

       int   localaddr(Map *map, Regs *regs, char *fn, char *val, ulong	*val)

       int   unwindframe(Map *map, Regs	*regs, ulong *next, Symbol *sym)

       int   windindex(char *regname)

       Loc*  windreglocs(void)

       Stacktrace  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 mem-
       ory.  The caller	may specify an initial register	set in the form	of  an
       Rgetter function, of the	form

	      ulong rget(Map *map, char	*name)

       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 SP and PC, and for the link	register (usu-
       ally LR)	on CISC	machines.

       Given the map and the rgetter, stacktrace unwinds the stack starting at
       the  innermost  function.   At  each  level  in the trace, it calls the
       tracer function,	which has the form

	      int trace(Map *map, ulong	pc, ulong callerpc,
		    Rgetter rget, Symbol *s)

       The tracer is passed the	map, the current program counter, the  program
       counter of the caller (zero if the caller is unknown), a	new rget func-
       tion, and a symbol (see describing the current function (nil if no sym-
       bol  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.

       The  rgetter  passed  to	the tracer is not the rgetter passed to	stack-
       trace 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 lget4,	 etc.,
       when evaluating the locations of	local variables.

       Localaddr  uses	stacktrace to walk up the stack	looking	for the	inner-
       most instance of	a function named fn ; once it finds the	 function,  it
       looks  for  the parameter or local variable var,	storing	the address of
       the variable in val.

       Unwindframe is the low-level function on	 which	stacktrace  is	built.
       Given  the  current memory image	in map and the current register	set in
       regs , unwindframe fills	in next	with the values	of the register	set at
       the  time  of  the call to the function in the current program counter.
       Sym should be the symbol	corresponding  to  the	current	 function,  if

       The  next array holds only the winding registers, typically the caller-
       save registers and the program counter and stack	pointer.  The order of
       registers  in  the  array is called the winding order.  The winding set
       can be found in the array mach->windreg,	which has  mach->nwindreg  en-
       tries.	Windindex returns the index of the named register in the wind-
       ing order.  Windreglocs returns an array	of Loc structures  correspond-
       ing to the winding registers, in	the winding order.

       The  following  code  writes  a	simple stack trace to standard output,
       stopping	after at most 20 stack frames.
	      static int
	      trace(Map	*map, ulong pc,	ulong callerpc,
		  Rgetter rget,	Symbol *s, int depth)
		  char buf[512];
		  int i, first;
		  u32int v;
		  Symbol s2;

		      print("%s+%lx", s->name, pc - loceval(s->loc));
		      print("%lux", pc);
		  first	= 0;
		  for(i=0; indexlsym(s,	&i, &s2)>=0; i++){
		      if(s.class != CPARAM)
			  print(", ");
		      if(lget4(map, rget, s->loc, &v) >= 0)
			  print("%s=%#lux", s->name, (ulong)v);
			  print("%s=???", s->name);
		  print(") called from ");
		  symoff(buf, sizeof buf, callerpc, CTEXT);
		  print("%s\n",	buf);
		  return depth < 20;

		  if(stacktrace(map, nil, trace) <= 0)
		      print("no	stack frame0);


       Need to talk about Regs



Want to link to this manual page? Use this URL:

home | help