Hello Guile!

I've been getting errors whilst backtraces are getting printed, they
look like this (I'm using Guile at tag `v3.0.9rc1` at `80bf3f48b`):

    Backtrace:
    In ice-9/boot-9.scm:
      1752:10  8 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
    In unknown file:
               7 (apply-smob/0 #<thunk 734d1a30f300>)
    In ice-9/boot-9.scm:
        724:2  6 (call-with-prompt _ _ #<procedure default-prompt-handler (k 
proc)>)
    In ice-9/eval.scm:
        619:8  5 (_ #(#(#<directory (guile-user) 734d1a312c80>)))
    In ice-9/boot-9.scm:
       2836:4  4 (save-module-excursion _)
      4388:12  3 (_)
    In test.scm:
        119:0  2 (_)
    In rnrs/base.scm:
    Exception thrown while printing backtrace:
    In procedure vector-ref: Argument 2 out of range: 72

After some rudimentary `(display ...)` debugging, I eventually hit
upon the `compute-predecessors` procedure in `module/system/vm/frame.scm`,
in particular, where we call `vector-ref` on `parsed`:

    (cond
     ((negative? target)
      (lp (1- to) (+ target (vector-ref parsed (1- to)))))
     ((positive? target)
      (lp (1+ to) (- target (vector-ref parsed to))))
     ((= to (vector-length preds))
      ;; This can happen when an arity fails to match.  Just ignore
      ;; this case.
      #t)
     (else
      (vector-set! preds to (cons from (vector-ref preds to)))))))

It looks like there's a bounds-check already in place, but it's the
last clause of the `cond` which makes it ineffectual unless `target`
is `0`. Perhaps it should come first in order to guard against
out-of-bounds access to `parsed`.

There's a patch attached to re-order the clauses.

Disclaimer: I'm well out of my depth in this code, so it's possible
I've got completely the wrong idea.

Thanks!
Shannon
From eb59e97165a5b9193b3f24aacc2c1ebc4d2fa23e Mon Sep 17 00:00:00 2001
From: Shannon Cole <shand...@fastmail.com>
Date: Tue, 4 Jun 2024 20:32:43 +1000
Subject: [PATCH] Fix out-of-bounds vector-ref when printing backtrace.

I've been getting errors whilst backtraces are getting printed, eg:

    In rnrs/base.scm:
    Exception thrown while printing backtrace:
    In procedure vector-ref: Argument 2 out of range: 72

It looks like the out-of-bounds guard is in last place when it should be
first. This commit re-orders them.

* module/system/vm/frame.scm (compute-predecessors): Re-order `cond` clauses to avoid out-of-bounds `vector-ref`
---
 module/system/vm/frame.scm | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/module/system/vm/frame.scm b/module/system/vm/frame.scm
index 6b14fc62a..12ae16e34 100644
--- a/module/system/vm/frame.scm
+++ b/module/system/vm/frame.scm
@@ -73,14 +73,14 @@
     (define (add-pred! from target)
       (let lp ((to from) (target target))
         (cond
+         ((= to (vector-length preds))
+          ;; This can happen when an arity fails to match.
+          ;; Just ignore this case.
+          #t)
          ((negative? target)
           (lp (1- to) (+ target (vector-ref parsed (1- to)))))
          ((positive? target)
           (lp (1+ to) (- target (vector-ref parsed to))))
-         ((= to (vector-length preds))
-          ;; This can happen when an arity fails to match.  Just ignore
-          ;; this case.
-          #t)
          (else
           (vector-set! preds to (cons from (vector-ref preds to)))))))
     (let lp ((n 0) (pos 0))
-- 
2.44.0

Reply via email to