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

From: Christopher Baines <[email-masked]>
Date: Tue, 11 Feb 2025 18:29:43 +0000

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:

  /gnu/store/lnlw64i4k06yphjbyr3ciy07mz9snlwg-guile-next-3.0.10-0.5d3f561/bin/guile  put-char-exn.scm > /dev/null

The output is somewhat variable, but on my system within a few seconds
it will output something like:

current-output-port: #<output: file 1> (encoding: UTF-8)

In ice-9/boot-9.scm:
  1762:12 17 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
In unknown file:
          16 (apply-smob/0 #<thunk 7f5dd6953fa0>)
In ice-9/threads.scm:
   165:20 15 (_)
In unknown file:
          14 (call-with-unblocked-asyncs #<procedure 7f5dd6953f40 at ice-9/thread…>)
In ice-9/boot-9.scm:
  1756:15 13 (with-exception-handler #<procedure 7f5dd6956fc0 at ice-9/boot-9.sc…> …)
  1762:12 12 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
   2217:5 11 (%start-stack thread _)
   2219:9 10 (_)
  1762:12  9 (with-exception-handler _ _ #:unwind? _ #:unwind-for-type _)
In /home/chris/Projects/Guile/guile/put-char-exn.scm:
    43:12  8 (_)
In unknown file:
           7 (simple-format #<output: file 1> "exception: ~A\n" #<&compound-excep…>)
In ice-9/boot-9.scm:
   1058:8  6 (default-record-printer #<&compound-exception components: (#<&exter…> …)
In unknown file:
           5 (write (#<&external-error> #<&origin origin: "fport_write"> #<&m…> …) …)
In ice-9/boot-9.scm:
   1050:4  4 (default-record-printer #<&origin origin: "fport_write"> #<output: f…>)
In unknown file:
           3 (display &origin #<output: file 1>)
In ice-9/boot-9.scm:
  1683:22  2 (raise-exception _ #:continuable? _)
In /home/chris/Projects/Guile/guile/put-char-exn.scm:
    29:25  1 (_ #<&compound-exception components: (#<&error> #<&origin origin: "p…>)
In unknown file:
           0 (make-stack #t)
ERROR: In procedure display:
ERROR:
  1. &error
  2. &origin: "put-char"
  3. &message: "conversion to port encoding failed"
  4. &irritants: 84
  5. &exception-with-kind-and-args:
      kind: encoding-error
      args: ("put-char" "conversion to port encoding failed" 84 #<output: file 1> #\&)

put-char-exn.scm:

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

(install-suspendable-ports!)

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

(define s
  (socket PF_UNIX
          (logior SOCK_STREAM SOCK_CLOEXEC SOCK_NONBLOCK)
          0))

(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)
                  (simple-format (current-output-port)
                                 "exception: ~A\n"
                                 exn))
              (lambda ()
                (with-throw-handler #t
                  (lambda ()
                    (put-bytevector s
                                    (string->utf8 "foo")))
                  (lambda (key . args)
                    (let* ((stack (make-stack #t 3))
                           (backtrace
                            (call-with-output-string
                              (lambda (port)
                                (display-backtrace stack port)
                                (newline port)))))
                      (display
                       backtrace
                       (current-output-port))))))
              #:unwind? #t)))))))
 (iota 2))

(sleep 60)