Steel Bank Common Lisp

Stack overflowing recursion of SB-PCL::UPDATE-CLASS while compiling defmethod's

Reported by Faré on 2012-05-19
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
High
Unassigned

Bug Description

Our large application QRes has a web of classes, with forward references to superclasses and to classes referred in methods and typechecking declarations. It compiles and runs fine with CCL 1.8, and compiles and mostly runs fine with SBCL 1.0.41.

While trying to update our SBCL, I find that it enters the low-level debugger with a stack overflow while compiling some defmethod or some other, with a backtrace that involves a great number of repetitions of the pattern below. Depending on whether I compile from clean or retry with previously built fasl, the failure moves, suggesting that the behavior is affected by side-effects of compile-file not present in the fasl. Also, the first failure (as reproducible by building from clean) can be averted by a
(eval-when (:compile-toplevel)
  (sb-mop:finalize-inheritance (find-class 'ticket-set)))
which suggests that SBCL is failing to automatically maintain the state of its inheritance graph.

There's a whole pile of infrastructure, and my feeble attempts at reproducing the bug on my side have been unsuccessful so far, but I could try harder.

The bug affects at least sbcl 1.0.56.60, 1.0.56, 1.0.55, 1.0.54, 1.0.53. I haven't tried 1.0.52 or earlier yet, which were known to have another bug preventing the compilation of this code base. Sigh.

Note: I am running on linux/x64.
It seems that my optimization settings while compiling and getting these errors are:
(optimize (speed 1) (space 1) (safety 3) (debug 3) (compilation-speed 1))

Faré (fahree) wrote :
Faré (fahree) wrote :

Note that there's a cycle of length 2 in the backtrace (elided in the attachment) between classes LEGACY-PNR and LEGACY-PNR-PAX, where each class refers to the other one in the :type declarations of its slots, its associated methods, and more places that may or may not matter.

I will attach a full cycle.?field.comment=Note that there's a cycle of length 2 in the backtrace (elided in the attachment) between classes LEGACY-PNR and LEGACY-PNR-PAX, where each class refers to the other one in the :type declarations of its slots.

I will attach a full cycle.

Faré (fahree) wrote :

Based on the stack trace, I could reconstitute a minimal test case.
Note that you need to load the file or evaluate the statements at the REPL,
for compiling them together will cause the finalization to happen early enough.

(declaim (optimize (speed 1) (space 1) (safety 3) (debug 3) (compilation-speed 1)))

(defpackage :bug (:use :cl))

(in-package :bug)

(defclass pax (sup)
  ((pnr :type (or null pnr))))

(defclass pnr (sup)
  ((pax :type (or null pax))))

(defclass sup ()
  ())

;;; COMMENT OUT TO WORK AROUND THE BUG..
;;(finalize-inheritance (find-class 'pnr))

(defmethod frob ((pnr pnr))
  (slot-value pnr 'pax))

Stas Boukarev (stassats) on 2012-05-19
Changed in sbcl:
status: New → Confirmed
importance: Undecided → High
Changed in sbcl:
assignee: nobody → Nikodemus Siivola (nikodemus)
status: Confirmed → In Progress
Nikodemus Siivola (nikodemus) wrote :

This should take care of it. Committing after freeze, since this regression has been in place for a fair while.

Nikodemus Siivola (nikodemus) wrote :

...modulo the BREAK calls I accidentally left in, of course.

Faré (fahree) wrote :

Same-day fix. You're awesome guys!

Nikodemus Siivola (nikodemus) wrote :

commit 522a3c95b9b7a044ff0ab8df1ca29460ef2ad3a7
Author: Nikodemus Siivola <email address hidden>
Date: Sun May 20 12:25:25 2012 +0300

    break infinite recursion in GENERATE-SLOTD-TYPECHECK

      Compilation of a typecheck can cause class finalization, which in turn can
      cause calls to GENERATE-SLOTD-TYPECHECK.

      Given the right sort of dependency graph, this can cause a cycle which needs
      to be broken.

      Regression from 1.0.46.11, fixed bug 1001799.

Changed in sbcl:
assignee: Nikodemus Siivola (nikodemus) → nobody
status: In Progress → Fix Committed
Nikodemus Siivola (nikodemus) wrote :

It would not have been so fast without a test case...

Stas Boukarev (stassats) on 2012-08-11
Changed in sbcl:
status: Fix Committed → Fix Released
status: Fix Released → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers