Skip to content

Output not shown when writing to a subshell process #4

@zaidhaan

Description

@zaidhaan

TL;DR: Neither stdout nor stderr (nevermind the colors) show up when writing to a subshell process as demonstrated below. Read further for GDB debugging findings.

$ cat test.sh
#!/usr/bin/env bash
echo stdout
echo elsewhere > >(cat)

$ ./test.sh
stdout
elsewhere

$ rederr ./test.sh
stdout

(Or if you want to do it in one line: rederr bash -c 'echo stdout ; echo elsewhere > >(cat)')


Works:

  • rederr bash -c 'cat <(echo stdout ; echo stderr >&2)' (both outputs shown, stderr colored)
  • rederr bash -c '( echo stdout ; echo stderr >&2 )' (both outputs shown, stderr colored)

Doesn't work:

  • rederr bash -c 'echo breaks > >(cat)' (no output)
  • rederr bash -c 'echo breaks >&2 > >(cat)' (no output)
  • rederr bash -c '( echo stdout ; echo stderr >&2 ) 2> >(cat) > >(cat)' (no output)

I figured I'd inspect this line just as a sanity check to check that "elsewhere" really doesn't end up in the output buffer:

rederr/rederr.c

Line 436 in 4ef6ede

n = write(is_stderr ? STDERR_FILENO : STDOUT_FILENO, p, l);

Now here's the confusing part! When I break on that line, it works fine! When I don't, it doesn't!

GDB with a break on line 436 followed by run and two continues
$ gdb -q ~/dev/repos/rederr/build/rederr
Reading symbols from /home/zai/dev/repos/rederr/build/rederr...
>>> b 436
Breakpoint 1 at 0x2540: file ../rederr.c, line 436.
>>> r ./test.sh > with_break.txt
Starting program: /home/zai/dev/repos/rederr/build/rederr ./test.sh > with_break.txt
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[Detaching after fork from child process 1073648]

Breakpoint 1, go (cmdline=0x7fffffffdec0) at ../rederr.c:436
436	                       n = write(is_stderr ? STDERR_FILENO : STDOUT_FILENO, p, l);
>>> c
Continuing.

Breakpoint 1, go (cmdline=0x7fffffffdec0) at ../rederr.c:436
436	                       n = write(is_stderr ? STDERR_FILENO : STDOUT_FILENO, p, l);
>>> c
Continuing.
[Inferior 1 (process 1073645) exited normally]
>>> quit

$ cat with_break.txt   
stdout
elsewhere
GDB with simply run
$ gdb -q ~/dev/repos/rederr/build/rederr
Reading symbols from /home/zai/dev/repos/rederr/build/rederr...
>>> run ./test.sh > no_break.txt
Starting program: /home/zai/dev/repos/rederr/build/rederr ./test.sh > no_break.txt
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[Detaching after fork from child process 1073347]
[Inferior 1 (process 1073344) exited normally]
>>> quit

$ cat no_break.txt  
stdout

I haven't got time to debug this further so I'll leave this bug report at that.

Edit: Just noticed that even valgrind --leak-check=full ./build/rederr ./test.sh also causes everything to work fine.


Version info:

  • rederr commit 4ef6ede (latest)
  • GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
  • GNU gdb (GDB) 13.1
  • gcc (GCC) 13.1.1 20230429
  • Linux 6.3.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions