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

Bug #1775384 reported by Dmytro
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Invalid
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

Revision history for this message
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  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.