|
From: Stas B. <sta...@gm...> - 2026-05-24 00:52:01
|
Fixed. Thanks.
On Fri, May 22, 2026 at 11:08 PM J Klein <je...@gm...> wrote:
>
>
>
> Unless I'm messing up, it seems that repeatedly using listen on a run-program output stream in what appears to be a non-recursive situation results in control stack exhaustion.
>
> The (read-yes) function below gives an error when using LISTEN but not when using READ-CHAR-NO-HANG for same purpose.
>
> This is a stripped down version of a function that runs an external program that performs a web connection and processes it, and outputs it. This one just calls /usr/bin/yes as the external process.
>
> Apologies in advance is this is some error on my part.
>
>
> cl-user> (lisp-implementation-version) ;; found no reference to listen in last few months of sbcl bug list
> "2.6.0"
>
> cl-user> (read-yes :listen nil) ;; using read-char-no-hang
> 8388608
>
>
>
> cl-user> (read-yes :listen t)
>
> Control stack exhausted (no more space for function call frames).
> This is probably due to heavily nested or infinitely recursive function
> calls, or a tail call that SBCL cannot or has not optimized away.
>
> PROCEED WITH CAUTION.
> [Condition of type sb-kernel::control-stack-exhausted]
>
> Restarts:
> 0: [retry] Retry SLIME REPL evaluation request.
> 1: [*abort] Return to SLIME's top level.
> 2: [abort] abort thread (#<thread tid=10499 "repl-thread" running {70051604A3}>)
>
> Backtrace:
> 0: (sb-kernel::control-stack-exhausted-error)
> 1: (sb-impl::fd-stream-misc-routine #<sb-sys:fd-stream for "descriptor 31" {70087B8853}> 0 0)
> 2: (listen #<sb-sys:fd-stream for "descriptor 31" {70087B8853}>)
>
> ------
>
> cl-user> *features*
> (:osicat-fd-streams :chunga :cl-fad :cl-ppcre :cl+ssl-homebrew-arm64-found
> :cl+ssl-macports-found :split-sequence :flexi-streams :xmls-nodes-are-structs
> :have-nr-wavelets chipz-system:gray-streams :swank :lparallel
> :lparallel.with-cltl2 :lparallel.with-cas :lparallel.with-stealing-scheduler
> :bordeaux-threads :global-vars :thread-support cffi-features:flat-namespace
> cffi-features:unix cffi-features:darwin :cffi cffi-sys::flat-namespace
> alexandria::sequence-emptyp :quicklisp :infix :asdf3.3 :asdf3.2 :asdf3.1
> :asdf3 :asdf2 :asdf :os-macosx :os-unix :non-base-chars-exist-p :asdf-unicode
> :arena-allocator :arm64 :gencgc :64-bit :ansi-cl :bsd :common-lisp :darwin
> :ieee-floating-point :little-endian :mach-o :package-local-nicknames
> :sb-core-compression :sb-ldb :sb-package-locks :sb-thread :sb-unicode :sbcl
> :unix)
>
>
>
>
>
> (defun read-yes (&key
> (listen t) ;; use LISTEN instead of READ-CHAR-NO-HANG
> (nwanted #.(expt 2 23)) ;; try to read this many butes
> (max-output-length #.(expt 2 24))) ;; safety read max
> (let ((proc (sb-ext:run-program "/usr/bin/yes" nil :input :stream :output :stream :error :stream :wait nil)))
> (let
> ((output-string
> (with-output-to-string (sout)
> (loop
> with in-stream = (sb-ext:process-output proc)
> with nbytes of-type fixnum = 0
> do
> ;; LISTEN causes stack exhaustion on arm64 darwin
> (if listen
> (loop until (not (listen in-stream))
> for c = (read-char in-stream nil nil)
> while c
> do (write-char c sout)
> (incf nbytes 1)
> (when (= nbytes nwanted) (return nil)))
> (loop for c = (read-char-no-hang in-stream nil nil)
> while c
> do (write-char c sout)
> (incf nbytes 1)
> (when (= nbytes nwanted) (return nil))))
> ;; when done, return
> (when (not (process-alive-p proc))
> (return nil))
> (when (= nbytes nwanted) ;; done
> (return nil))
> (when (> nbytes max-output-length)
> (error "External process output too long."))))))
>
> (length output-string))))
> _______________________________________________
> Sbcl-bugs mailing list
> Sbc...@li...
> https://lists.sourceforge.net/lists/listinfo/sbcl-bugs
|