mstorsjo / msvc-wine

Scripts for setting up and running MSVC in Wine on Linux
Other
684 stars 83 forks source link

Problem with closing piped output due to msvctricks.exe #83

Closed mstorsjo closed 1 year ago

mstorsjo commented 1 year ago

CC @huangqinjin

Since the introduction of the msvctricks.exe binary, closing the output pipe of the compiler causes hangs.

To reproduce:

$ echo '#include <vector>' > file.cpp
$ cl -E file.cpp | less

Within less, type q to stop reading the input (after only consuming a screenful of output, from the preprocessing output which is large enough to block the pipe buffers). Normally I would expect all processes to exit at this point (possibly with some complaints due to the broken pipe). With msvctricks.exe in place, I instead get a hang. If I remove msvctricks.exe so that this only uses the redirections done in wine-msvc.sh, this works as expected.

huangqinjin commented 1 year ago

I reproduced the issue.

demo.cpp

#include <stdio.h>
int main(int argc, char* argv[])
{
    FILE* f = argv[1] ? fopen(argv[1], "w") : stdout;
    for (int i = 0; i < 100000; ++i)
        fprintf(f, "%d\n", i);
    return 119;
}
g++ demo.cpp -o demo
/opt/msvc/bin/x64/cl demo.cpp

Use stdout

$ ./demo | head -n1 >/dev/null; echo "${PIPESTATUS[@]}"
141 0
$ wine64 demo.exe | head -n1 >/dev/null; echo "${PIPESTATUS[@]}"
119 0

Use FIFO

$ mkfifo fifo
$ { cat fifo || echo "cat $?">&2  &  ./demo fifo || echo "demo $?">&2; } | head -n1 >/dev/null
cat 141
demo 141
$ { cat fifo || echo "cat $?">&2  &  wine64 demo.exe fifo || echo "demo $?">&2; } | head -n1 >/dev/null
cat 141
<hangs>
$ { cat fifo || echo "cat $?">&2  &  wine64 demo.exe >fifo || echo "demo $?">&2; } | head -n1 >/dev/null
cat 141
demo 119

Wine handles SIGPIPE differently for stdout and other fds (logs are from strace output):

The proposed solution is to manually kill wine after cat exits.