File:  [gforth] / gforth / backtrac.fs
Revision 1.15: download - view: text, annotated - select for diffs
Sun Dec 31 13:39:11 2006 UTC (17 years, 3 months ago) by anton
Branches: MAIN
CVS tags: HEAD
updated copyright years

    1: \ backtrace handling
    2: 
    3: \ Copyright (C) 1999,2000,2003,2004,2006 Free Software Foundation, Inc.
    4: 
    5: \ This file is part of Gforth.
    6: 
    7: \ Gforth is free software; you can redistribute it and/or
    8: \ modify it under the terms of the GNU General Public License
    9: \ as published by the Free Software Foundation; either version 2
   10: \ of the License, or (at your option) any later version.
   11: 
   12: \ This program is distributed in the hope that it will be useful,
   13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: \ GNU General Public License for more details.
   16: 
   17: \ You should have received a copy of the GNU General Public License
   18: \ along with this program; if not, write to the Free Software
   19: \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   20: 
   21: 
   22: \ growing buffers that need not be full
   23: 
   24: struct
   25:     cell% 0 * field buffer-descriptor \ addr u
   26:     cell% field buffer-length
   27:     cell% field buffer-address
   28:     cell% field buffer-maxlength \ >=length
   29: end-struct buffer%
   30: 
   31: : init-buffer ( addr -- )
   32:     buffer% %size erase ;
   33: 
   34: : adjust-buffer ( u addr -- )
   35:     \G adjust buffer% at addr to length u
   36:     \ this may grow the allocated area, but never shrinks it
   37:     dup >r buffer-maxlength @ over <
   38:     if ( u )
   39: 	r@ buffer-address @ over resize throw r@ buffer-address !
   40: 	dup r@ buffer-maxlength !
   41:     then
   42:     r> buffer-length ! ;
   43: 
   44: \ backtrace stuff
   45: 
   46: create backtrace-rs-buffer buffer% %allot drop
   47: \ copy of the return stack at throw
   48: 
   49: : init-backtrace ( -- )
   50:     backtrace-rs-buffer init-buffer ;
   51:     
   52: init-backtrace
   53: 
   54: :noname ( -- )
   55:     DEFERS 'cold
   56:     init-backtrace ;
   57: IS 'cold
   58: 
   59: : backtrace-return-stack ( -- addr u )
   60:     \ addr is the address of top element of return stack (the stack
   61:     \ grows downwards), u is the number of aus that interest us on the
   62:     \ stack.
   63:     rp@ in-return-stack?
   64:     if
   65: 	rp@ [ 2 cells ]L +
   66:     else \ throw by signal handler with insufficient information
   67: 	handler @ cell - \ beyond that we know nothing
   68:     then
   69:     backtrace-rp0 @ [ 1 cells ]L - over - 0 max ;
   70: 
   71: :noname ( -- )
   72:     backtrace-return-stack
   73:     dup backtrace-rs-buffer adjust-buffer
   74:     backtrace-rs-buffer buffer-address @ swap move ;
   75: IS store-backtrace
   76: 
   77: : print-bt-entry ( return-stack-item -- )
   78:     cell - dup in-dictionary? over dup aligned = and
   79:     if
   80: 	@ dup threaded>name dup if
   81: 	    .name drop
   82: 	else
   83: 	    drop dup look if
   84: 		.name drop
   85: 	    else
   86: 		drop body> look \ !! check for "call" in cell before?
   87: 		if
   88: 		    .name
   89: 		else
   90: 		    drop
   91: 		then
   92: 	    then
   93: 	then
   94:     else
   95: 	drop
   96:     then ;
   97: 
   98: : print-backtrace ( addr1 addr2 -- )
   99:     \G print a backtrace for the return stack addr1..addr2
  100:     cr ." Backtrace:"
  101:     swap u+do
  102: 	cr
  103: 	i @ dup hex. ( return-addr? )
  104: 	print-bt-entry
  105: 	cell +loop ;
  106: 
  107: :noname ( -- )
  108:     backtrace-rs-buffer 2@ over + print-backtrace ;
  109: IS dobacktrace
  110: 
  111: [ifdef] defer-default
  112: :noname
  113:     r@ >stderr cr ." deferred word " print-bt-entry ." is uninitialized" ;
  114: is defer-default
  115: [then]

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>