gc full doesn't clean weak-pointer in class instance slot

Bug #1775384 reported by Dmytro on 2018-06-06
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

I'm not sure that whether it's a bug, but here is the description.

1. Why does behavior of this too form is different?
The first form uses bar structure for holding an array of foo structure with a weak pointer:
(progn
  (defstruct foo
    (ref nil :type (or null sb-ext:weak-pointer)))

  (defstruct bar
    (items (make-array (list 1) :element-type 'foo :initial-element (make-foo))
           :type (simple-array foo)))

  (let ((bar-obj (make-bar)))
    (let* ((val (list 10)))
      (setf (aref (slot-value bar-obj 'items) 0)
            (make-foo :ref (sb-ext:make-weak-pointer val))))
    (sb-ext:gc :full t)
    (print (aref (slot-value bar-obj 'items) 0))))
This form produces expected print with the broken weak pointer:
#S(FOO :REF #<broken weak pointer>)
The second form uses bar class for holding an array of foo structure with a weak pointer:
(progn
  (defstruct foo
    (ref nil :type (or null sb-ext:weak-pointer)))

  (defclass bar-class ()
    ((items :type (simple-array foo)
            :initform (make-array (list 1)
                                  :element-type 'foo
                                  :initial-element (make-foo)))))

  (let ((bar-obj (make-instance 'bar-class)))
    (let* ((val (list 10)))
      (setf (aref (slot-value bar-obj 'items) 0)
            (make-foo :ref (sb-ext:make-weak-pointer val))))
    (sb-ext:gc :full t)
    (print (aref (slot-value bar-obj 'items) 0))))
This form produces the print with the same weak pointer:
#S(FOO :REF #<weak pointer: (10)>)

2. I'm using sbcl 1.3.14.
3. Linux dlyman 4.4.0-127-generic #153-Ubuntu SMP Sat May 19 10:58:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Douglas Katzman (dougk) wrote :

Not a bug.
To assert stuff about what is/isn't provably reachable in such a narrow scope as these contrived examples, you have to make sure that local variables aren't acting as roots.
A pointer to the recently consed list may linger on the stack for various reasons.
In case it does; in the other case it doesn't. There's nothing to explain this at the language level; it's based on the assembly code's behavior, and whether the stack frame word that held a pointer to the thing you expect to have become unreachable got overwritten.

Changed in sbcl:
status: New → Invalid
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers