Changeset 6647


Ignore:
Timestamp:
Jun 3, 2007, 2:44:23 AM (17 years ago)
Author:
Gary Byers
Message:

New (args + locals) scheme for backtraces, "stack inspection".

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/ide-1.0/ccl/lib/describe.lisp

    r6620 r6647  
    10421042(defun record-type-p (name &optional check-database)
    10431043  (declare (ignore check-database))
    1044   (ignore-errors (ccl::%foreign-type-or-record name)))
     1044  (and (keywordp name)
     1045       (ignore-errors (ccl::%foreign-type-or-record name))))
    10451046
    10461047; Add arglist here.
     
    14781479
    14791480;;; Still needs work.
     1481;;; Lots of work.
    14801482(defclass thread-inspector (uvector-inspector) ())
    14811483
     
    14841486
    14851487(defmethod compute-line-count :before ((i thread-inspector))
    1486   (when (eq (inspector-object i) ccl::*current-lisp-thread*)
    1487     (ccl::%normalize-areas)))
     1488)
    14881489
    14891490(defmethod line-n ((thread thread-inspector) n)
    14901491  (declare (ignore n))
    1491   (multiple-value-bind (value label type) (call-next-method)
    1492     (values
    1493      (or (and (fixnump value)
    1494               (>= value 0)
    1495               (memq label '(ccl::sg.xframe ccl::sg.cs-area ccl::sg.vs-area
    1496                             ccl::sg.ts-area ccl::sg.cs-overflow-limit))
    1497               (%int-to-ptr (ash value 2)))
    1498          value)
    1499      label
    1500      type)))
     1492)
    15011493
    15021494#|
     
    15231515
    15241516
    1525 #+ppc-target
    1526 (progn
     1517
    15271518;;;;;;;
    15281519;;
     
    15401531  ((addresses :accessor addresses)
    15411532   (restart-info :accessor restart-info)
    1542    (sampling-period :initarg :sampling-period :initform 32 :reader sampling-period)
    1543    (stack-start :initarg :stack-start :initform (ccl::%get-frame-ptr) :reader stack-start)
    1544    (stack-end :initarg :stack-end :initform (ccl::last-frame-ptr) :reader stack-end)
     1533   (stack-start :initarg :stack-start  :reader stack-start)
     1534   (stack-end :initarg :stack-end :reader stack-end)
    15451535   (tcr :initarg :tcr :initform (ccl::%current-tcr) :reader tcr)
    15461536   (context :initarg :context :reader context)
     
    15531543 
    15541544
    1555 ; This is set up to access the result of
    1556 ; (multiple-value-call #'vector (ccl::parent-frame-saved-vars ...))
    1557 (ccl::def-accessors svref
    1558   %sv.frame
    1559   %sv.last-catch
    1560   %sv.srv)
    1561 
    1562 
    1563 
    1564 (defun ignore-function-in-backtrace? (error-frame function)
    1565   (loop for ignored-fn in (ignored-functions error-frame)
    1566         when (and (null function) (eq ignored-fn :kernel)) return t
    1567         when (and (symbolp ignored-fn) (eq (function-name function) ignored-fn)) return t
    1568         when (eq ignored-fn function) return t
    1569         finally (return nil)))
    1570 
    1571 ; use parent-frame-saved-vars to cons a vector for each element of ADDRESSES
     1545
    15721546(defmethod initialize-instance ((f error-frame) &key)
    15731547  (call-next-method)
     
    15751549
    15761550(defmethod initialize-addresses ((f error-frame))
    1577   (let ((end (stack-end f)))
    1578     (flet ((skip-to-important-frame (frame context)
    1579              (loop for this? = (or (eq frame end)
    1580                                    (not (ignore-function-in-backtrace?
    1581                                          f
    1582                                          (ccl::cfp-lfun frame))))
    1583                    until this?
    1584                    do (setf frame (ccl::parent-frame frame context))
    1585                    finally (return frame))))
    1586       (setf (slot-value f 'stack-start)
    1587             (skip-to-important-frame (stack-start f) (context f)))))
    1588   (let* ((count 0)
    1589          (context (context f))
    1590          (p (stack-start f))
    1591          (p-child (ccl::child-frame p context))
    1592          (q (stack-end f))
    1593          (period (sampling-period f))
    1594          (addresses nil)
    1595          (last-frame nil))
    1596     (multiple-value-bind (frame catch srv)
    1597         (ccl::last-catch-since-saved-vars p-child context)
    1598       (loop
    1599         (if (null frame) (error "Can't find saved vars info"))
    1600         (if (eq frame p-child) (return))
    1601         (multiple-value-setq (frame catch srv)
    1602           (ccl::parent-frame-saved-vars context frame catch srv srv)))
    1603       (push (vector p-child catch (ccl::copy-srv srv))
    1604             addresses)
    1605       (setq last-frame frame)
    1606       (multiple-value-setq (frame catch srv)
    1607         (ccl::parent-frame-saved-vars context frame catch srv srv))
    1608       (unless (eq frame p) (error "(~s (~s ~d)) <> ~d"
    1609                                   'ccl::parent-frame 'ccl::child-frame p p))
    1610       (push (vector frame catch (ccl::copy-srv srv))
    1611             addresses)
    1612       (flet ((done-p ()
    1613                (or (null frame) (eql last-frame q))))
    1614         (block loop
    1615           (do* ((cnt (1+ period)))
    1616                ((done-p))
    1617             (loop while (ignore-function-in-backtrace?
    1618                          f (ccl::cfp-lfun frame))
    1619                   do
    1620                   (setq last-frame frame)
    1621                   (multiple-value-setq (frame catch srv)
    1622                     (ccl::parent-frame-saved-vars context frame catch srv srv))
    1623                   (when (done-p) (return-from loop)))
    1624             (when (eql 0 (decf cnt))
    1625               (setq cnt period)
    1626               (push (vector frame catch (ccl::copy-srv srv))
    1627                     addresses))
    1628             (setq last-frame frame)
    1629             (multiple-value-setq (frame catch srv)
    1630               (ccl::parent-frame-saved-vars context frame catch srv srv))
    1631             (incf count))))
    1632       (setf (frame-count f) count
    1633             (addresses f) (list-to-vector (nreverse addresses))))))
    1634 
    1635 (defun error-frame-n (error-frame n)
    1636   (let* ((addresses (addresses error-frame))
    1637          (period (sampling-period error-frame))
    1638          (context (context error-frame))
    1639          p child)
    1640     (flet ((skipping-uninteresting-parent-frames (child)
    1641             (loop while (ignore-function-in-backtrace?
    1642                          error-frame (ccl::cfp-lfun (ccl::parent-frame child context)))
    1643                   do (setq child (ccl::parent-frame child context))
    1644                   finally (return child))))
    1645       (unless (< -1 n (frame-count error-frame))
    1646         (setq n (require-type n `(integer 0 ,(1- (frame-count error-frame))))))
    1647       (if (eql 0 n)
    1648         (setq child (%sv.frame (svref addresses 0))
    1649               p (%sv.frame (svref addresses 1)))
    1650         (multiple-value-bind (idx offset) (floor (1- n) period)
    1651           (setq child (skipping-uninteresting-parent-frames
    1652                        (%sv.frame (svref addresses (1+ idx)))))
    1653           (dotimes (i offset)
    1654             (declare (fixnum i))
    1655             (setq child (skipping-uninteresting-parent-frames
    1656                          (ccl::parent-frame child context))))
    1657           (setq p (ccl::parent-frame child context))))
    1658       (values p child))))
    1659 
    1660 (defmethod error-frame-address-n ((f error-frame) n)
    1661   (multiple-value-bind (p child) (error-frame-n f n)
    1662     (multiple-value-bind (lfun pc) (ccl::cfp-lfun p)
    1663       (values p lfun pc child))))
    1664 
    1665 ; Returns 6 values:
    1666 ; p lfun pc child last-catch srv
    1667 ; Where the last-catch & register values are those for the CHILD's frame
    1668 ; (the ones we need to look at to display values for frame P).
    1669 (defmethod error-frame-regs-n ((f error-frame) n)
    1670   (let* ((addresses (addresses f))
    1671          (period (sampling-period f))
    1672          (context (context f))
    1673          p child last-catch srv)
    1674     (unless (< -1 n (frame-count f))
    1675       (setq n (require-type n `(integer 0 ,(1- (frame-count f))))))
    1676     (if (eql 0 n)
    1677       (let ((child-sv (svref addresses 0)))
    1678         (setq child (%sv.frame child-sv)
    1679               last-catch (%sv.last-catch child-sv)
    1680               srv (ccl::copy-srv (%sv.srv child-sv))))
    1681       (multiple-value-bind (idx offset) (floor (1- n) period)
    1682         (let ((child-sv (svref addresses (1+ idx))))
    1683           (setq child (%sv.frame child-sv)
    1684                 last-catch (%sv.last-catch child-sv)
    1685                 srv (ccl::copy-srv (%sv.srv child-sv))))
    1686         (flet ((maybe-ignore ()
    1687                  (loop while (ignore-function-in-backtrace?
    1688                               f
    1689                               (ccl::cfp-lfun (ccl::parent-frame child context)))
    1690                      do (multiple-value-setq (child last-catch srv)
    1691                           (ccl::parent-frame-saved-vars context child last-catch srv srv)))))
    1692          (maybe-ignore)
    1693            (dotimes (i offset)
    1694              (declare (fixnum i))
    1695              (multiple-value-setq (child last-catch srv)
    1696                (ccl::parent-frame-saved-vars context child last-catch srv srv))
    1697             (maybe-ignore)
    1698             ))))
    1699     (unless child (error "shouldn't happen"))
    1700     (setq p (ccl::parent-frame child context))
    1701     (multiple-value-bind (lfun pc) (ccl::cfp-lfun p)
    1702       (values p lfun pc child last-catch srv))))
    1703      
     1551  (let* ((addresses (list-to-vector (ccl::%stack-frames-in-context (context f)))))
     1552      (setf (frame-count f) (length addresses)
     1553            (addresses f) addresses)))
     1554
     1555(defmethod compute-frame-info ((f error-frame) n)
     1556  (let* ((frame (svref (addresses f) n))
     1557         (context (context f)))
     1558    (multiple-value-bind (lfun pc) (ccl::%cfp-lfun frame)
     1559      (multiple-value-bind (args locals) (ccl::arguments-and-locals context frame lfun pc)
     1560        (list (ccl::arglist-from-map lfun) args locals)))))
    17041561
    17051562(defun print-error-frame-limits (f stream)
     
    17171574;;
    17181575
    1719 ;;; True to show more info about backtrace frames
    1720 (defvar *show-backtrace-frame-addresses* nil)
    1721 
     1576
     1577
     1578;;; The "vsp-range" and "tsp-range" slots have to do with
     1579;;; recognizing/validating stack-allocated objects
    17221580(defclass stack-inspector (inspector)
    1723   ((show-frame-addresses :initform *show-backtrace-frame-addresses*
    1724                          :accessor show-frame-addresses)
    1725    (vsp-range :accessor vsp-range :initarg :vsp-range)
    1726    (tsp-range :accessor tsp-range :initarg :tsp-range)))
     1581  ((vsp-range :accessor vsp-range :initarg :vsp-range)
     1582   (tsp-range :accessor tsp-range :initarg :tsp-range)
     1583   (csp-range :accessor csp-range :initarg :csp-range)))
    17271584
    17281585
     
    17451602           :tsp-range (make-tsp-stack-range tcr context)
    17461603           :vsp-range (make-vsp-stack-range tcr context)
     1604           :csp-range (make-csp-stack-range tcr context)
    17471605           initargs)))
    17481606
     
    17541612  (addresses (inspector-object f)))
    17551613
    1756 (defmethod error-frame-address-n ((f stack-inspector) n)
    1757   (error-frame-address-n (inspector-object f) n))
    1758 
    1759 (defmethod error-frame-regs-n ((f stack-inspector) n)
    1760   (error-frame-regs-n (inspector-object f) n))
    1761 
    17621614(defmethod compute-line-count ((f stack-inspector))
    1763   (setf (show-frame-addresses f) *show-backtrace-frame-addresses*)
    17641615  (frame-count (inspector-object f)))
    17651616
    17661617(defmethod line-n ((f stack-inspector) n)
    1767   (multiple-value-bind (p lfun) (error-frame-address-n (inspector-object f) n)
    1768     (values lfun
    1769             (if (show-frame-addresses f) p n)
    1770             (if lfun :static '(:comment (:bold) (:plain :italic))) 'prin1-colon-line)))
    1771 
    1772 (defmethod prin1-label ((i stack-inspector) stream value &optional label type)
    1773   (declare (ignore value type))
    1774   (if (show-frame-addresses i)
    1775     (format stream "#x~x/#x~x"
    1776             (ccl::index->address label) (ccl::index->address (ccl::%frame-savevsp label)))
    1777     (call-next-method)))
    1778 
    1779 (defmethod prin1-value ((i stack-inspector) stream value &optional label type)
    1780   (declare (ignore label type))
    1781   (if value
    1782     (ccl::%lfun-name-string value stream)
    1783     (write-string "kernel" stream)))
    1784 
    1785 (defmethod line-n-inspector ((f stack-inspector) n value label type)
    1786   (declare (ignore value label type))
    1787   (multiple-value-bind (p lfun pc) (error-frame-address-n (inspector-object f) n)
    1788     (declare (ignore p))
    1789     (make-instance (inspector-class lfun) :object lfun :pc pc)))
     1618  (let* ((frame (svref (addresses (inspector-object f)) n)))
     1619    (ccl::cfp-lfun frame)))
     1620
     1621
     1622
     1623 
     1624
    17901625
    17911626;;; inspecting a single stack frame
     
    17931628(defclass stack-frame-inspector (inspector)
    17941629  ((frame-number :initarg :frame-number :initform nil :reader frame-number)
    1795    (frame-info :accessor frame-info)
    1796    (label-columns :accessor label-columns)
    1797    (saved-register-count :accessor saved-register-count)))
     1630   (frame-info :initform nil :accessor frame-info)))
    17981631
    17991632
     
    18071640  (setf (frame-number i) frame-number))
    18081641
    1809 (defun integer-digits (integer &optional (base 10))
    1810   (setq integer (require-type integer 'fixnum))
    1811   (do ((digits (if (< integer 0) 2 1) (1+ digits))
    1812        (n (abs integer) (floor n base)))
    1813       ((if (< n base) (return digits)))))   
     1642   
    18141643
    18151644(defmethod compute-line-count ((i stack-frame-inspector))
     
    18181647      0
    18191648      (let* ((error-frame (inspector-object i))
    1820              (frame-info (multiple-value-list
    1821                           (error-frame-regs-n error-frame frame-number))))
    1822         (setf (frame-info i) frame-info)
    1823         (let ((count (ccl::count-values-in-frame
    1824                       (car frame-info)          ; this frame
    1825                       (context error-frame)
    1826                       (cadddr frame-info))))    ; child frame
    1827           (setf (label-columns i) (integer-digits count))
    1828           (let ((lfun (cadr frame-info))
    1829                 (pc (caddr frame-info)))
    1830             (declare (ignore p))
    1831             (+ count (setf (saved-register-count i)
    1832                            (logcount (or (ccl::registers-used-by lfun pc) 0))))))))))
     1649             (frame-info (or (frame-info i)
     1650                             (setf (frame-info i) (compute-frame-info error-frame frame-number)))))
     1651        (destructuring-bind (args locals) (cdr frame-info)
     1652          (+ 1 (length args) 1 (length locals)))))))
    18331653
    18341654(defmethod line-n ((i stack-frame-inspector) n)
    18351655  (unless (< -1 n (inspector-line-count i))
    18361656    (line-n-out-of-range i n))
    1837   (let ((frame-info (frame-info i))
    1838         (saved-register-count (saved-register-count i)))
    1839     (if (< n saved-register-count)
    1840       (multiple-value-bind (mask regs) (apply #'ccl::saved-register-values (cdr frame-info))
    1841         (let* ((srv (nth 5 frame-info))
    1842                (unresolved (ccl::srv.unresolved srv))
    1843                (j ccl::*saved-register-count*)
    1844                (i n))
    1845           (loop
    1846             (loop (if (logbitp (decf j) mask) (return)))
    1847             (if (< (decf i) 0) (return)))
    1848           (let ((name (saved-register-name
    1849                        (elt ccl::*saved-register-numbers* (- ccl::*saved-register-count* 1 j)) (cadr frame-info) (caddr frame-info))))
    1850             (values (if (setq unresolved (logbitp j unresolved))
    1851                       *unbound-marker*
    1852                       (ccl::srv.register-n regs (- ccl::*saved-register-count* 1 j)))
    1853                     (cons n
    1854                           (cons (elt ccl::*saved-register-names* j) name))
    1855                     (if unresolved :static :normal)))))
    1856       (destructuring-bind (p lfun pc &rest rest) frame-info
    1857         (declare (ignore rest))
    1858         (let ((offset (- n saved-register-count)))
    1859           (multiple-value-bind (var type name)
    1860                                (ccl::nth-value-in-frame p offset (context (inspector-object i)) lfun pc)
    1861             (values var (cons n (cons type name)) :normal)))))))
     1657  (destructuring-bind (arglist args locals) (frame-info i)
     1658    (if (zerop n)
     1659      (values arglist nil :static)
     1660      (let* ((nargs (length args)))
     1661        (decf n)
     1662        (if (< n nargs)
     1663          (cons :arg (nth n args))
     1664          (progn
     1665            (decf n nargs)
     1666            (if (zerop n)
     1667              nil
     1668              (cons :local (nth (1- n) locals)))))))))
    18621669
    18631670(defmethod (setf line-n) (value (i stack-frame-inspector) n)
    1864   (unless (< -1 n (inspector-line-count i))
    1865     (line-n-out-of-range i n))
    1866   (let ((frame-info (frame-info i))
    1867         (saved-register-count (saved-register-count i)))
    1868     (if (< n saved-register-count)
    1869       (let* ((mask (apply #'ccl::saved-register-values (cdr frame-info)))
    1870              (srv (nth 5 frame-info))
    1871              (unresolved (ccl::srv.unresolved srv))
    1872              (j ccl::*saved-register-count*)
    1873              (i n))
    1874         (loop
    1875           (loop (if (logbitp (decf j) mask) (return)))
    1876           (if (< (decf i) 0) (return)))
    1877         (if (logbitp j unresolved) (line-n-out-of-range i n))
    1878         (apply #'ccl::set-saved-register value (- ccl::*saved-register-count* 1 j) (cdr frame-info)))
    1879       (destructuring-bind (p lfun pc child &rest rest) frame-info
    1880         (declare (ignore lfun pc rest))
    1881         (let ((offset (- n saved-register-count))
    1882               (context (context (inspector-object i))))
    1883           (ccl::set-nth-value-in-frame p offset context value child))))))
    1884 
    1885 (defun saved-register-name (reg lfun pc)
    1886   (let* ((map (ccl::function-symbol-map lfun))
    1887          (names (car map))
    1888          (info (cdr map))
    1889          (j 0))
    1890     (dotimes (i (length names))
    1891       (when (and (eq reg (aref info j))
    1892                  (<= (aref info (1+ j)) pc (aref info (+ j 2))))
    1893         (return (aref names i)))
    1894       (incf j 3))))
     1671  (declare (ignorable value n))
     1672  (error "not yet!"))
     1673
    18951674       
    18961675
    1897 (defmethod prin1-label ((i stack-frame-inspector) stream value &optional label type)
    1898   (declare (ignore value type))
    1899   (format stream "~vd: " (label-columns i) (car label)))
     1676
    19001677
    19011678(defmethod prin1-value ((i stack-frame-inspector) stream value &optional label type)
    1902   (declare (ignore type))
    1903   (destructuring-bind (n type . name) label
    1904     (declare (ignore n))
    1905     (if name (format stream "~s " name))
    1906     (if type (format stream "(~a) " type))
    1907     (if (eq value *unbound-marker*)
    1908       (format stream "??")
    1909       (prin1 value stream))))
     1679  (declare (ignore label type))
     1680  (when value
     1681    (if (or (atom value) (not (typep (car value) 'keyword)))
     1682      (prin1 value stream)
     1683      (progn
     1684        (if (eq (car value) :arg)
     1685          (format stream "   ")
     1686          (format stream "  "))
     1687        (when (cdr value)
     1688          (destructuring-bind (label . val) (cdr value)
     1689            (format stream "~a: " label)
     1690            (if (eq val *unbound-marker*)
     1691              (format stream "??")
     1692              (prin1 val stream))))))))
    19101693
    19111694(defmethod (setf frame-number) (frame-number (i stack-frame-inspector))
     
    19181701    (setf (inspector-line-count i) nil)
    19191702    frame-number))
    1920 )
    1921 
     1703
     1704
     1705;;; Each of these stack ranges defines the entire range of (control/value/temp)
     1706;;; addresses; they can be used to addresses of stack-allocated objects
     1707;;; for printing.
    19221708(defun make-tsp-stack-range (tcr bt-info)
    19231709  (list (cons (ccl::%catch-tsp (ccl::bt.top-catch bt-info))
     
    19391725                                target::area.high))))
    19401726
     1727#+ppc-target
     1728(defun make-csp-stack-range (tcr bt-info)
     1729  (list (cons (ccl::%svref (ccl::bt.top-catch bt-info) target::catch-frame.csp-cell)
     1730              (ccl::%fixnum-ref (ccl::%fixnum-ref tcr target::tcr.cs-area)
     1731                                target::area.high))))
     1732
     1733#+x8664-target
     1734(defun make-csp-stack-range (tcr bt-info)
     1735  (list (cons (ccl::%svref (ccl::bt.top-catch bt-info) target::catch-frame.foreign-sp-cell)
     1736              (ccl::%fixnum-ref (ccl::%fixnum-ref tcr target::tcr.cs-area)
     1737                                target::area.high))))
    19411738
    19421739
Note: See TracChangeset for help on using the changeset viewer.