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

Re: Redirecting a programs job control messages to parent's STDOUT



In case any later readers are interested in this question, I've posted an answer
below which came to me via _another_ answer by a certain Vartan Simonian (thanks
Vartan!)

------------------------------------------------------------

You can get zsh to print the segmentation fault message from the job if you
start it as a background job and then immediately bring it to the foreground.

    "$exepath" "$@" &
    fg

This will cause zsh to print out messages for signals on the job started for
$exepath.

The downside is that you will get a little bit more than you bargained for:

    % crun faulty.c
    faulty.c:1:5: warning: ‘main’ is usually a function [-Wmain]
     int main=0;
         ^~~~
    [2] 2080
    [2]  - running    "$exepath" "$@"
    zsh: segmentation fault (core dumped)  "$exepath" "$@"

But as shown, you will get the segfault messages printed in the terminal.

Because the messages are printed by the interactive shell, not the failing
process, the job messages won't get redirected should you try to redirect stdout
or stderr.

So on the one hand, should you try to take useful output out of your running
process and redirect it somewhere else, you don't need to worry about the job
messages getting in the way. But this also means you won't get the segfault
message should you try to redirect it by redirecting stderr.

Here's a demonstration of this effect, with line breaks added in-between
commands for clarity:

    % crun good.c > test
    [2] 2071
    [2]  - running    "$exepath" "$@"

    % cat test
    Hello, world!

    % crun faulty.c 2>test
    [2] 2092
    [2]  - running    "$exepath" "$@"
    zsh: segmentation fault (core dumped)  "$exepath" "$@"

    % cat test
    faulty.c:1:5: warning: ‘main’ is usually a function [-Wmain]
     int main=0;
         ^~~~



- zv

On 07/10/2017 02:16 PM, zv wrote:
> I've defined a function in my .zshrc to compile & run a file with the function
> below:
> 
>   crun() {
>       local file=$1
>       shift
>       local exepath="$(mktemp)"
> 
>       if [[ $file =~ "\.c$" ]]; then
>           gcc -g -Wall $file -o $exepath || return $?
>       else
>           echo "no filetype detected"
>           return 126
>       fi
> 
>       $exepath "$@"
>   }
> 
> Which is called like so:
> 
>   % crun source.cc arg_1 arg_2
> 
> This works for normal program, but has the problem that the shell's job control
> messages, such as those generated from a segfault, do not appear.
> 
> As an example:
> 
>   % echo 'int main=0' >> /tmp/faulty.c # a crashing c program
>   % crun faulty.c
>   % # no output generated
> 
> Whereas the equivalent interactive commands would generate this:
> 
>   % g++ faulty.c -o /tmp/faulty && /tmp/faulty
>   [1] 2894 segmentation fault (core dumped) # 🢀 zsh's job control output for
> SIGSEGV
> 
> I've tried a number of different ways to trap the signal or have the invoking
> ("parent") shell to treat "constructed binaries" identically to an ordinary
> executable/command but nothing seems to work without a hacks large enough to
> morally bankrupt me.
> 
> Is there any way to display these messages for a crashing executable whose path
> is dynamically calculated? Ideally without writing your own trap/signal handlers
> + exec, using `sh -c "$exepath $@"`, or writing a totally new program entirely)
> 
> - zv
> 
> 




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