Clojure stack traces via source registry + native frame walk
A direct-link build emits (jolt-register-source! short-name ns name file line) once per fn def — at definition time, so zero per-call cost. On an uncaught error the reporter walks Chez's native continuation frames (jolt-throw captures the live continuation via call/cc; host conditions carry their own &continuation), maps each frame's procedure name through the registry, and prints a Clojure backtrace 'ns/name (file:line)'. Wired into both the cli and a built binary's launcher. Frames are keyed by the short munged fn name Chez actually reports (emit-fn's letrec self-binding), not jv$ns$name; a cross-namespace collision degrades to the bare frame name rather than a wrong attribution. The analyzer carries the original form's position through defn macroexpansion onto the def node. Calling a non-fn now throws a catchable ClassCastException (via jolt-throw) naming the operator, instead of a raw Chez error. Caveats (documented in source-registry.ss): names map only in direct-link/AOT closed-world builds — the open-world -e/repl/run path falls back to the top-level location; and pervasive TCO erases tail-call frames, so a mapped trace shows only the non-tail spine. JOLT_DEBUG_FRAMES dumps raw frame names. Re-mint (analyzer + backend); prelude byte-identical (direct-link off during mint). Corpus rows certified, build-smoke asserts the trace.
This commit is contained in:
parent
9bf3d1c80e
commit
57bab5d409
12 changed files with 288 additions and 105 deletions
|
|
@ -337,18 +337,20 @@
|
|||
;; ns + register aliases before this ns's forms; dce
|
||||
;; keeps original order.
|
||||
(let ((src (read-file-string (cdr nf))))
|
||||
(append
|
||||
(map (lambda (s) (dce-rec #t #f '() s))
|
||||
(bld-ns-prelude (car nf) src))
|
||||
(ei-emit-ns-records (car nf) src))))
|
||||
(parameterize ((rdr-source-file (cdr nf)))
|
||||
(append
|
||||
(map (lambda (s) (dce-rec #t #f '() s))
|
||||
(bld-ns-prelude (car nf) src))
|
||||
(ei-emit-ns-records (car nf) src)))))
|
||||
ordered))
|
||||
(string-append entry-ns "/-main"))
|
||||
(values #f
|
||||
(apply append
|
||||
(map (lambda (nf)
|
||||
(let ((src (read-file-string (cdr nf))))
|
||||
(append (bld-ns-prelude (car nf) src)
|
||||
(bld-emit-ns (car nf) src))))
|
||||
(parameterize ((rdr-source-file (cdr nf)))
|
||||
(append (bld-ns-prelude (car nf) src)
|
||||
(bld-emit-ns (car nf) src)))))
|
||||
ordered))
|
||||
#f)))
|
||||
(lambda ()
|
||||
|
|
@ -400,7 +402,10 @@
|
|||
" (list \"jolt-core\" \"stdlib\"))))\n"))
|
||||
(put-string out (string-append
|
||||
" (let ((mainv (var-deref " (ei-str-lit entry-ns) " \"-main\")))\n"
|
||||
" (apply jolt-invoke mainv args))\n"
|
||||
;; render an uncaught throw (+ Clojure backtrace) instead
|
||||
;; of Chez's opaque dump, then exit non-zero.
|
||||
" (guard (v (#t (jolt-report-throwable v (current-error-port)) (exit 1)))\n"
|
||||
" (apply jolt-invoke mainv args)))\n"
|
||||
" (exit 0)))\n"))
|
||||
(close-port out))
|
||||
;; 4. compile -> boot -> embed -> link.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue