IO bug

Vibhu Mohindra vibhu.mohindra at
Thu Jun 30 01:05:46 UTC 2016


I've got a file open for IO. Only writing to it works okay. But if I
also try to read from it, then things start going wrong. I've attached a
test case that should return NIL but instead raises an error in ABCL
(1.3.3, on OSX).

The problem is with the call to #'write-sequence on line 21.

In fact, from some other tests, I believe that replacing that call to
#'write-sequence with a call to a function that does the same thing but
by repeatedly setting the file-position and writing a byte, for each
byte in the sequence, fixes things. That means something about
#'write-sequence is broken.

Maybe I misunderstand the file level functions in Common Lisp, and my
test doesn't use them correctly. However, the test passes in: CLISP,
CCL, CMUCL, SBCL, ECL. So I thought I'd report this, just in case it is
a bug in ABCL.

Also, removing the last three lines of code in #'main, which read one
byte, makes the test run without errors.

-------------- next part --------------
(defparameter *iters* 10000)
(defparameter *array-size* 1025) ;on abcl, *array-size* >= 1024 => fail

(defun main ()
  (with-open-file (stream "io_test.tmp"
                       :element-type '(unsigned-byte 8)
                       :direction :io
                       :if-exists :overwrite
                       :if-does-not-exist :create)
    (let ((b (make-array *array-size*
                         :element-type '(unsigned-byte 8)
                         :initial-element 0)))
      (do ((i 0 (1+ i))
           (nbytes (random (length b)) (random (length b))))
          ((>= i *iters*))
        (if (or (zerop (random 2)) (zerop (file-length stream)))
          (let ((before (file-length stream)))
            (assert before)
            (assert (file-position stream (file-length stream)))
            ;(assert (file-position stream :end))
            (write-sequence b stream :end nbytes)
            (finish-output stream)
            (assert (= nbytes (- (file-length stream) before))
                    "iter ~A: expected file-length to change by ~A bytes not ~A"
                    (- (file-length stream) before)))
            (assert (file-position stream (random (file-length stream))))
            (read-byte stream)))))))

;abcl (1.3.2)
;#<THREAD "interpreter" {4997BAB}>: Debugger invoked on condition of type SIMPLE-ERROR
;  iter 179: expected file-length to change by 1642 bytes not 760
;  0: CONTINUE  Retry assertion.
;  1: TOP-LEVEL Return to top level.
;the finish-output fix for other lisps did not help here
;using symbol :end instead of file-length when calling #'file-position
;  didn't help either

;ecl fails (even for 1024 byte array)
;Condition of type: SIMPLE-ERROR
;iter 2: expected file-length to change by 1246 bytes not 1024
;fixed by calling finish-output before assertion

;sbcl also fails
;debugger invoked on a SIMPLE-ERROR in thread
;#<THREAD "main thread" RUNNING {1002A01083}>:
;  iter 0: expected file-length to change by 860 bytes not 0
;fixed by calling #'finish-output

;cmucl fails
;Error in function LISP::ASSERT-ERROR:
;   iter 0: expected file-length to change by 24 bytes not 0
;   [Condition of type SIMPLE-ERROR]
;fixed by calling #'finish-output

;ccl is okay (even without needing to call #'finish-output)
;clisp is okay (even without needing to call #'finish-output)

More information about the armedbear-devel mailing list