[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Getting trace info from MACL
- To: firstname.lastname@example.org (Charlie Lindahl)
- Subject: Re: Getting trace info from MACL
- From: Gary Byers <email@example.com>
- Date: Wed, 21 Mar 1990 10:03:15 EST
- Cc: firstname.lastname@example.org
- In-reply-to: Your message of Wed, 21 Mar 90 03:12:48 CST
I have an application which will soon be placed in a (semi-) production
environment. I'd like to:
1) Catch ALL errors and log them.
2) Record, as part of #1, the stack trace so's I can isolate the
function that caused the error.
#1 is no problem (wrap the top-level form in a (catch-error-quietly)).
But how can I do #2? I tried using APROPOS/INSPECT to go routing around
in the trace tables, but no luck. Do I have to do my own *EVENTHOOK*, or
is there some neat hack that does the trick? I am running version 1.2.2...
Thanx in advance,
Charlie S. Lindahl
Automation and Robotics Research Institute
University of Texas at Arlington
There really should be a dressed-up version of this in the product, but there
isn't. Calling (FUNCTION-CALL-HISTORY) should return pretty much the same
information that backtrace does. Famous last words: I guess I'd be interested
in hearing about cases where it doesn't ...
(defun stack-frame-function (ptr)
(setq ptr (%inc-ptr ptr -4))
(let ((highbyte (%get-byte ptr))) ; Tsk, tsk.
(if (or (= highbyte #x1f) (= highbyte 1))
(%get-ptr (%int-to-ptr (logand (%get-long ptr) #x00ffffff))))
; This doesn't identify saved values of bound specials or "value cells" shared
; by compiled closures as such; sorry ...
(defun stack-frame-values (ptr)
(flet ((frame-start-addr (addr)
(%get-ptr (%inc-ptr (logand #x00ffffff (%get-long addr)) -4)))
(do* ((p (%inc-ptr addr -4) (%inc-ptr p -4)))
((= (%get-byte p) #x1f) p))))
(do* ((startfp (frame-start-addr ptr) (%inc-ptr startfp -4))
(childfp (frame-start-addr (child-frame ptr)))
((eq startfp childfp) (nreverse vals))
(let ((marker (%get-byte startfp)))
(unless (or (= marker 1) (= marker #x1f))
(push (%get-ptr startfp) vals))))))
(defun function-call-history ()
(do* ((result nil)
(pos (%inc-ptr (ccl::%get-frame-ptr) 4) (%inc-ptr pos 4))
(end (%int-to-ptr (logand -3 (%get-long (%int-to-ptr #x908))))))
((eq pos end) result)
(when (= (%get-byte pos) #x1f)
(push (cons (stack-frame-function pos)
Using FUNCTION-CALL-HISTORY when CATCH-ERROR-QUIETLY indicates that an error
occurred would return information for all pending functions "between" the
toplevel-function and the function containing the CATCH-ERROR-QUIETLY, but
wouldn't show anything between that function and the one which signalled the
One way to get the latter functionality would be to redefine ERROR (and
CERROR, BREAK, etc.) to call FUNCTION-CALL-HISTORY before or instead of
their usual behavior. Unfortunately, since these functions are block-
compiled into the Lisp kernel, redefining them in such a way that all of
their callers see the new definitions involves much gnashing of teeth ...
If there's interest, I'll try to explain how to do this someday.