Subject: Re: bug#75658: Non-deterministic Gash error in‘gcc-mesboot-4.9.4’

From: Ludovic Courtès <[email-masked]>
Date: Fri, 14 Mar 2025 01:00:05 +0100

Ludovic Courtès <[email-masked]> skribis:

> In gash/shell.scm:
>  289: 9 [sh:substitute-command #<procedure 2da0f560 at gash/eval.scm:129:35 ()>]
>  270: 8 [%subshell #<procedure v ()>]
> In ice-9/boot-9.scm:
>  157: 7 [catch quit #<procedure v ()> ...]
> In ice-9/r4rs.scm:
>  176: 6 [with-output-to-port #<variable 2de5dc00 value: #<output: file /dev/pts/19>> ...]
> In srfi/srfi-1.scm:
>  619: 5 [for-each #<procedure eval-sh (exp)> ((<sh-exec> "expr" # ":" ...))]
> In gash/shell.scm:
>  129: 4 [sh:exec-let () "expr" ...]
>   92: 3 [exec-utility () ...]
> In srfi/srfi-1.scm:
>  616: 2 [for-each #<procedure 2d60f0a0 at gash/shell.scm:70:12 (i)> (0 1 2 ...)]
> In ice-9/boot-9.scm:
> 1473: 1 [dup->port #<input: file /dev/pts/19> "r0" 7]
> In unknown file:
>    ?: 0 [fdopen 7 "r0"]
>
> ERROR: In procedure fdopen:
> ERROR: In procedure scm_fdes_to_port: Bad file descriptor

I was able to capture an strace log of this:

--8<---------------cut here---------------start------------->8---
15837 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fb10dad7850) = 15838
15838 set_robust_list(0x7fb10dad7860, 24) = 0
15837 wait4(15838,  <unfinished ...>
15838 close(3)                          = 0
15838 close(4)                          = 0
15838 pipe2([3, 4], O_CLOEXEC)          = 0
[...]
15838 clone3({flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, child_tid=0x7fb10beaa990, parent_tid=0x7fb10beaa990, exit_signal=0, stack=0x7fb10b51b000, stack_size=0x98ef80, tls=0x7fb10beaa6c0} => {parent_tid=[15839]}, 88) = 15839
15839 rseq(0x7fb10beaafe0, 0x20, 0, 0x53053053 <unfinished ...>
15838 rt_sigprocmask(SIG_SETMASK, [],  <unfinished ...>
[...]
15838 lseek(2, 0, SEEK_CUR)             = -1 ESPIPE (Illegal seek)
15839 close(10)                         = 0
15839 close(17 <unfinished ...>
15838 dup2(22, 6 <unfinished ...>
15839 <... close resumed>)              = 0
15838 <... dup2 resumed>)               = 6
15839 close(6 <unfinished ...>
15838 fcntl(6, F_GETFL <unfinished ...>
15839 <... close resumed>)              = 0
15838 <... fcntl resumed>)              = -1 EBADF (Bad file descriptor)
15839 close(7)                          = 0
15839 close(18)                         = 0
15839 close(15)                         = 0
15839 close(12)                         = 0
15839 close(9)                          = 0
15839 close(16)                         = 0
15838 write(2, "Backtrace:\n", 11)      = 11
--8<---------------cut here---------------end--------------->8---

The sequence goes like this:

  1. A child process (15837) corresponding to the subshell is created;

  2. That process creates a finalization thread (15839);

  3. Main thread does dup2(22, 6); finalization does close(6); main
     thread does fcntl(6, F_GETFL), which fails with EBADF.

I suspect something like a wrong revealed count on the relevant ports,
possibly those created in ‘install-current-ports!’.

Ludo’.