Frame bindings referring to non-existent locals

  • Done
  • quality assurance status badge
Details
2 participants
  • Ludovic Courtès
  • Andrew Whatson
Owner
unassigned
Submitted by
Andrew Whatson
Severity
normal
A
A
Andrew Whatson wrote on 20 Sep 2022 09:16
(address . bug-guile@gnu.org)
CAPE069dRtJvi4yMAm5ZauDmj7t40QnOxvkkRRB0yPZ+y893-0g@mail.gmail.com
Hello Guilers!

I have some buggy code which fails to compile. While printing the backtrace of
this compilation error, another error occurs and Guile reports "Exception thrown
while printing backtrace".

To reproduce the error:

$ cd guile-prescheme
$ git checkout d793730895aaeb4ee203f062ab3864af8fd1d5fd
$ guild compile -L . ps-compiler/prescheme/flatten.scm

<...snip...>
In ice-9/eval.scm:
626:19 7 (_ #<directory (ps-compiler prescheme linking) 7ff7692f…>)
293:34 6 (_ #(#(#<directory (prescheme bcomp package) 7ff766…>) …))
293:34 5 (_ #(#(#<directory (prescheme bcomp package) 7ff766…>) …))
214:21 4 (_ #(#(#<directory (prescheme bcomp package) 7ff766…>) …))
217:50 3 (lp (#<procedure 7ff7654c3f80 at ice-9/eval.scm:123:…> …))
217:33 2 (lp (#<procedure 7ff7654c3f60 at ice-9/eval.scm:182:…> …))
Exception thrown while printing backtrace:
In procedure frame-local-ref: Argument 2 out of range: 1

ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Wrong type to apply: #<srfi-69:hash-table real-table: #<hash-table 7faf5e6...
<...snip...>

To investigate further, I've run the compile script from the repl and dug around
for the responsible frame:

> ,use (scripts compile)
> (compile "-L" "." "ps-compiler/prescheme/flatten.scm")
;; fails, enters debugger
[1]> ,bt
;; fails to print backtrace
[1]> ,m (system vm frame)
[1]> ,use (system repl common) (system repl debug) (srfi srfi-43)
[1]> (debug-frames (repl-debug (car (fluid-ref *repl-stack*))))
;; $1 is a vector of frame objects
[1]> (define (dump-frame i f) (format #t "~a: ~a\n" i f) (frame-arguments f))
[1]> (vector-for-each dump-frame $1)
;; fails on frame index 2
[2]> (define (dump-binding b) (format #t "~a\n" b))
[2]> (frame-num-locals (vector-ref $1 2))
;; problem frame has 1 local slot
[2]> (for-each dump-binding (frame-bindings (vector-ref $1 2)))
#<<binding> frame: #<frame 7fee83f4c440 lp> idx: 0 name: closure slot: 0 ...
#<<binding> frame: #<frame 7fee83f4c440 lp> idx: 1 name: args slot: 1 ...
[2]> (frame-num-locals (vector-ref $1 3))
;; parent frame has 2 local slots
[2]> (for-each dump-binding (frame-bindings (vector-ref $1 3)))
#<<binding> frame: #<frame 7fee83f4c430 lp> idx: 0 name: closure slot: 0 ...
#<<binding> frame: #<frame 7fee83f4c430 lp> idx: 1 name: args slot: 1 ...

From this, it looks like there's a broken frame which has 2 bindings, but only 1
local slot, leading to the "out of range" error while printing the backtrace.
Curiously, its parent frame has the same 2 bindings, and 2 local slots as
expected.

Any ideas what is happening here?

Cheers,
Andrew
A
L
L
Ludovic Courtès wrote on 12 Oct 2022 22:34
Re: [PATCH] Avoid 'frame-local-ref' errors when printing backtrace.
(name . Andrew Whatson)(address . whatson@gmail.com)
87czawvl0v.fsf@gnu.org
Hi Andrew,

Andrew Whatson <whatson@gmail.com> skribis:

Toggle quote (5 lines)
> Workaround for https://bugs.gnu.org/57948.
>
> * module/system/vm/frame.scm (frame-call-representation): Treat a
> binding as "unspecified" if its slot exceeds 'frame-num-locals'.

Yay, great to see that fixed (or almost)!

It would be great if you could add a simple test case though, so that
the bug doesn’t eventually come back to haunt us.

Could you send an updated patch?

Thanks,
Ludo’.

PS: BTW, it’ll be great to have more patches from you! :-) To that end,
please check out the new Guile copyright policy and let us know what
option you’d like to choose:
A
A
Andrew Whatson wrote on 13 Oct 2022 05:36
(name . Ludovic Courtès)(address . ludo@gnu.org)
CAPE069eQb3Yg9OdgjBw3tC2c-G2Cbo15rjkdjP=uQgvu_MNjpA@mail.gmail.com
Ludovic Courtès <ludo@gnu.org> wrote:
Toggle quote (6 lines)
>
> It would be great if you could add a simple test case though, so that
> the bug doesn’t eventually come back to haunt us.
>
> Could you send an updated patch?

Ah yes, getting this covered in a test is on my list. I had trouble
writing a reproducer previously, I think the bug might only occur in a
nested compilation context (top-level error compiling a dependency
module), but I'll have another go.

Toggle quote (5 lines)
> PS: BTW, it’ll be great to have more patches from you! :-) To that end,
> please check out the new Guile copyright policy and let us know what
> option you’d like to choose:
> <https://lists.gnu.org/archive/html/guile-devel/2022-10/msg00008.html>.

I have already assigned copyright of my work on Guile to the FSF,
happy for that to remain.

That said, I'm glad to see this requirement being eased!

Cheers,
Andrew
L
L
Ludovic Courtès wrote on 13 Oct 2022 15:09
(name . Andrew Whatson)(address . whatson@gmail.com)
87fsfrrhtv.fsf@gnu.org
Hi,

Andrew Whatson <whatson@gmail.com> skribis:

Toggle quote (12 lines)
> Ludovic Courtès <ludo@gnu.org> wrote:
>>
>> It would be great if you could add a simple test case though, so that
>> the bug doesn’t eventually come back to haunt us.
>>
>> Could you send an updated patch?
>
> Ah yes, getting this covered in a test is on my list. I had trouble
> writing a reproducer previously, I think the bug might only occur in a
> nested compilation context (top-level error compiling a dependency
> module), but I'll have another go.

Awesome.

Toggle quote (8 lines)
>> PS: BTW, it’ll be great to have more patches from you! :-) To that end,
>> please check out the new Guile copyright policy and let us know what
>> option you’d like to choose:
>> <https://lists.gnu.org/archive/html/guile-devel/2022-10/msg00008.html>.
>
> I have already assigned copyright of my work on Guile to the FSF,
> happy for that to remain.

Oh sorry I had overlooked that, perfect!

Thanks,
Ludo’.
A
A
Andrew Whatson wrote on 11 Jan 2023 06:24
(name . Ludovic Courtès)(address . ludo@gnu.org)
CAPE069deSOMm8ZoDRd_opj46Rn_0UX3T0uhRUw0xL71QPQsWWg@mail.gmail.com
Ludovic Courtès <ludo@gnu.org> wrote:
Toggle quote (4 lines)
>
> It would be great if you could add a simple test case though, so that
> the bug doesn’t eventually come back to haunt us.

I've finally tracked this one down, a patch with a unit test for this
bug is attached.

Cheers,
Andrew
commit 164bdce6acf53796cb96ef1930a89c6caf84bc39
Author: Andrew Whatson <whatson@gmail.com>
Date: Wed Jan 11 14:04:32 2023 +1000

Test for 'frame-local-ref' errors when printing backtrace.
This test reproduces the error from https://bugs.gnu.org/56493, and
passes with the workaround which was merged in commit
c7fa78fc751eb336bcfafbb5ac59c460ee2c5d7a.
* test-suite/tests/eval.test ("avoid frame-local-ref out of range"): New
test.

Toggle diff (41 lines)
diff --git a/test-suite/tests/eval.test b/test-suite/tests/eval.test
index 9d20812f2..316153385 100644
--- a/test-suite/tests/eval.test
+++ b/test-suite/tests/eval.test
@@ -22,6 +22,7 @@
:use-module ((system vm vm) :select (call-with-stack-overflow-handler))
:use-module ((system vm frame) :select (frame-call-representation))
:use-module (ice-9 documentation)
+ :use-module (ice-9 exceptions)
:use-module (ice-9 local-eval))
@@ -387,7 +388,27 @@
(and (eq? (car (frame-call-representation (car frames)))
'make-stack)
(eq? (car (frame-call-representation (car (last-pair frames))))
- 'with-exception-handler)))))
+ 'with-exception-handler))))
+
+ (pass-if "avoid frame-local-ref out of range"
+ (with-exception-handler
+ (lambda (ex)
+ ;; If frame-call-representation fails, we'll catch that
+ ;; instead of the expected "Wrong type to apply" error.
+ (string-prefix? "Wrong type to apply" (exception-message ex)))
+ (lambda ()
+ (with-exception-handler
+ (lambda (ex)
+ (let* ((stack (make-stack #t))
+ (frames (stack->frames stack)))
+ (for-each frame-call-representation frames))
+ (raise-exception ex))
+ (lambda ()
+ ;; This throws a "Wrong type to apply" error, creating a
+ ;; frame with an incorrect number of local slots as
+ ;; described in bug <https://bugs.gnu.org/56493>.
+ (primitive-eval '(define foo (#t))))))
+ #:unwind? #t)))
;;;
;;; letrec init evaluation
L
L
Ludovic Courtès wrote on 12 Jan 2023 00:03
(name . Andrew Whatson)(address . whatson@gmail.com)
87sfggishx.fsf@gnu.org
Hi,

Andrew Whatson <whatson@gmail.com> skribis:

Toggle quote (13 lines)
> commit 164bdce6acf53796cb96ef1930a89c6caf84bc39
> Author: Andrew Whatson <whatson@gmail.com>
> Date: Wed Jan 11 14:04:32 2023 +1000
>
> Test for 'frame-local-ref' errors when printing backtrace.
>
> This test reproduces the error from <https://bugs.gnu.org/56493>, and
> passes with the workaround which was merged in commit
> c7fa78fc751eb336bcfafbb5ac59c460ee2c5d7a.
>
> * test-suite/tests/eval.test ("avoid frame-local-ref out of range"): New
> test.

Applied, thanks!

Ludo’.

PS: Please use ‘git format-patch’ so the patch can be directly consumed
by ‘git am’.
Closed
A
A
Andrew Whatson wrote on 12 Jan 2023 03:09
(name . Ludovic Courtès)(address . ludo@gnu.org)
CAPE069cyBas-3XjtE7s1myyDPPiCv=TG4iP7mh1shd=Wa8A6mw@mail.gmail.com
Ludovic Courtès <ludo@gnu.org> wrote:
Toggle quote (3 lines)
>
> Applied, thanks!

Thank you!

Toggle quote (3 lines)
> PS: Please use ‘git format-patch’ so the patch can be directly consumed
> by ‘git am’.

My mistake, sorry about that. Noted for next time :)

Cheers,
Andrew
Closed
?