Subject: bug#62590: Strange put-char encoding-error "conversion to port encoding failed"

From: Christopher Baines <[email-masked]>
Date: Tue, 11 Feb 2025 19:06:46 +0000

Christopher Baines <[email-masked]> writes:

> Christopher Baines <[email-masked]> writes:
>
>> I've been seeing some strange occasional errors for a while now.
>
> ...
>
>> I'm not sure what the 84 means? If I'm picking out the characters that
>> have failed to be encoded, I'm not sure why some of these would fail
>> (like space or w)?
>>
>> Unfortunately I'm not sure how to reproduce this. Suspendable ports
>> might be a factor here as that is probably in use.
>
> Still seeing these errors, including today. I've managed to stumble on a
> reliable and somewhat minimal way of reproducing them:

Here's a slightly simplified version with some comments:

(use-modules (ice-9 binary-ports)
             (rnrs bytevectors)
             (ice-9 exceptions)
             (ice-9 threads)
             (system repl debug))

(setvbuf (current-output-port) 'line)
(setvbuf (current-error-port) 'line)

(simple-format (current-error-port)
               "current-output-port: ~A (encoding: ~A)\n\n"
               (current-output-port)
               (port-encoding (current-output-port)))

(for-each
 (lambda (i)
   (call-with-new-thread
    (lambda ()
      (with-exception-handler
          (lambda (exn)
            (let ((stack (make-stack #t)))
              (print-frames (stack->vector stack)
                            (current-error-port)
                            #:count (stack-length stack))
              (print-exception
               (current-error-port)
               (stack-ref stack 3)
               '%exception
               (list exn)))
            (force-output (current-error-port))

            (primitive-exit 1))
        (lambda ()
          (while #t
            (with-exception-handler
                (lambda (exn)
                  ;; The put-char error seems to happen around here
                  (simple-format (current-output-port)
                                 "exception: ~A\n"
                                 exn)
                  #f)
              (lambda ()
                (with-throw-handler #t
                  (lambda ()
                    ;; Cause some error, I think any error will do
                    (+ 'a 1))
                  (lambda (key . args)
                    (let* ((stack (make-stack #t 3))
                           (backtrace
                            (call-with-output-string
                              (lambda (port)
                                (display-backtrace stack port)
                                (newline port)))))
                      (display
                       ;; Printing the backtrace seems significant,
                       ;; other strings don't seem to reproduce the
                       ;; behaviour
                       backtrace
                       (current-output-port))
                      #f))))
              #:unwind? #t)))))))
 (iota 2))

(sleep 60)