Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: zsh segfault bug from 5.9.1-1 onwards



On Fri, Aug 7, 2026 at 9:25 AM Châu Trác Thịnh <234thinh275@xxxxxxxxx> wrote:
>
> I'm on Arch Linux, and a script of mine started to segfault after updating from 5.9-6 to 5.9.1-1.
>
> Minimal reproduction: run the following
> ```
> (echo 1 | cat & (echo 2))
> ```
>
> There's no segfault when:
>
> Reverting to 5.9-6
> removing either of the parenthesis
> removing any command in the chain (replacing them can still segfault; my original code is quite different)

After break fork and fiddling with set follow-fork-mode I managed to
follow the correct child,
Thread 4.1 "zsh" received signal SIGSEGV, Segmentation fault.
0x0000000000462cde in havefiles () at jobs.c:1620
1620    peekfirst(jobtab[i].filelist)) {
(gdb) bt
#0  0x0000000000462cde in havefiles () at jobs.c:1620
#1  0x00000000004394b0 in execcmd_exec (state=0x7ffcf7998710,
eparams=0x7ffcf79979c0,
    input=0, output=0, how=18, last1=1, close_if_forked=-1) at exec.c:3719
#2  0x0000000000434bf1 in execpline2 (state=0x7ffcf7998710, pcode=707,
how=18, input=0,
    output=0, last1=1) at exec.c:2070
#3  0x0000000000433834 in execpline (state=0x7ffcf7998710,
slcode=10242, how=18, last1=1)
    at exec.c:1795
(gdb) p *jobtab[i].filelist
$2 = {list = {first = 0x0, last = 0x22af360, flags = 0}, node = {next = 0x0,
    prev = 0x22af360, dat = 0x0}}

As we can see here, first is NULL, and peekfirst does
->list.first->dat which crashes. The problem was introduced in
zw/51404: Nullify filelist after deleting (fix segfault)
d3edf318306e37d2d96. The problem isn't that it nullifies the filelist,
but how it checks for that later.

I think this is the fix:

diff --git i/Src/jobs.c w/Src/jobs.c
index 657d62ea0b..fef3c708e5 100644
--- i/Src/jobs.c
+++ w/Src/jobs.c
@@ -1617,7 +1617,7 @@ havefiles(void)

     for (i = 1; i <= maxjob; i++)
        if (jobtab[i].stat && jobtab[i].filelist &&
-           peekfirst(jobtab[i].filelist)) {
+           nonempty(jobtab[i].filelist)) {
            return 1;
        }
     return 0;

Which instead just checks if ->list.first == NULL.

-- 
Mikael Magnusson




Messages sorted by: Reverse Date, Date, Thread, Author