Message ID | 20150813120643.GF430@redhat.com |
---|---|
State | New |
Headers | show |
Hello! > Looking at the code in vl.c I see a hack for SDL introduced in > > commit 59a36a2f6728081050afc6ec97d0018467999f79 > Author: Stefan Weil <weil@mail.berlios.de> > Date: Thu Jun 18 20:11:03 2009 +0200 > > Win32: Fix compilation with SDL. Just a hint which may have to do with this. Looks like SDL introduces its own entry point, but it's WinMain() instead of main(). In this case standard CRT setup is omitted. But it is very easy to recover in this case. Just call: freopen("CONOUT$", "w", stderr); This performs the necessary setup and relinks CRT's stderr with Windows console stream. It is a well known hack. More info here: http://stackoverflow.com/questions/9020790/using-stdin-with-an-allocconsole Kind regards, Pavel Fedin Expert Engineer Samsung Electronics Research center Russia
On Thu, Aug 13, 2015 at 01:06:43PM +0100, Daniel P. Berrange wrote: > When debugging some patches on Windows, I discovered that nothing printed > to stderr ever appears on the console. Eventually I discovered that if I > build with --disable-sdl, then stderr appears just fine. > > Looking at the code in vl.c I see a hack for SDL introduced in > > commit 59a36a2f6728081050afc6ec97d0018467999f79 > Author: Stefan Weil <weil@mail.berlios.de> > Date: Thu Jun 18 20:11:03 2009 +0200 > > Win32: Fix compilation with SDL. > > > If I mostly kill the hack from vl.c, and just leave a plain '#undef main' > then I get working console stderr once again. [snip] > to get it to print an error about bad -object arg. The message > never appears unless I apply that patch above, though I lack any > explanation as to why this is happening, aside from "SDL black magic" So I figured out what's going on here The sdl-config program is adding "-Dmain=SDL_main" to the compiler flags. So when vl.c does this: #include <SDL.h> int qemu_main(int argc, char **argv, char **envp); int main(int argc, char **argv) { return qemu_main(argc, argv, NULL); } #undef main #define main qemu_main We have an extra level of substitution going on. So we end up the program starting in a main(int argc, char **argv) that is provided by SDL.dll, which in turn calls this stub we define at the top of vl.c: int main(int argc, char **argv) { return qemu_main(argc, argv, NULL); } where 'main' is actually changed to 'SDL_main', and 'qemu_main' is auctally the real 'main' at the bottom of vl.c Looking in SDL sources, one of the things it does in its replacement main() method is to kill off default stdout & stderr streams, replacing them with a stream that writes data to stdout.txt and stderr.txt in the current directory. As well as breaking the ability to see error messages on stderr, this stupid SDL redirection also breaks the ability to use the monitor via '-monitor stdio'. All this is done even if you are not actually using SDL as the QEMU display output too. By replacing that current hack: #include <SDL.h> int qemu_main(int argc, char **argv, char **envp); int main(int argc, char **argv) { return qemu_main(argc, argv, NULL); } #undef main #define main qemu_main With just #include <SDL.h> #undef main we get rid of SDL.dll's replacement main() method entirely and execution directly starts in QEMU's main() from vl.c. This avoids the stupid console output redirection SDL does, and AFAICT, the SDL UI still works after this, so the other setup things SDL.dll does don't seem to be too critical Regards, Daniel
Am 13.08.2015 um 14:06 schrieb Daniel P. Berrange: > When debugging some patches on Windows, I discovered that nothing printed > to stderr ever appears on the console. Eventually I discovered that if I > build with --disable-sdl, then stderr appears just fine. > > Looking at the code in vl.c I see a hack for SDL introduced in > > commit 59a36a2f6728081050afc6ec97d0018467999f79 > Author: Stefan Weil <weil@mail.berlios.de> > Date: Thu Jun 18 20:11:03 2009 +0200 > > Win32: Fix compilation with SDL. > > > If I mostly kill the hack from vl.c, and just leave a plain '#undef main' > then I get working console stderr once again. > Hi Daniel, that's a feature of SDL 1.2: stdout and stderr are by default redirected to files stdout.txt and stderr.txt in the executable's directory. This redirection can be disabled by an environment variable (SDL_STDIO_REDIRECT="no"). On my Linux machines, I always set this variable, so when I run QEMU for Windows with wine32 or wine64, stdout and stderr work. Printing to stdout / stderr on Windows can be an adventure: depending on your shell (command.exe, cmd.exe, MinGW shell, MinGW rxvt, Cygwin shell, ...) it works different, and I also had application crashes when a GUI application which was not started from a shell tried to print to stdout. From a user's point of view, maybe a better solution than the current one would be a GTK console window which displays any output to stdout / stderr. Regards Stefan
On Thu, Aug 13, 2015 at 07:48:47PM +0200, Stefan Weil wrote: > Am 13.08.2015 um 14:06 schrieb Daniel P. Berrange: > > When debugging some patches on Windows, I discovered that nothing printed > > to stderr ever appears on the console. Eventually I discovered that if I > > build with --disable-sdl, then stderr appears just fine. > > > > Looking at the code in vl.c I see a hack for SDL introduced in > > > > commit 59a36a2f6728081050afc6ec97d0018467999f79 > > Author: Stefan Weil <weil@mail.berlios.de> > > Date: Thu Jun 18 20:11:03 2009 +0200 > > > > Win32: Fix compilation with SDL. > > > > > > If I mostly kill the hack from vl.c, and just leave a plain '#undef main' > > then I get working console stderr once again. > > > > Hi Daniel, > > that's a feature of SDL 1.2: stdout and stderr are by default > redirected to files stdout.txt and stderr.txt in the executable's > directory. > > This redirection can be disabled by an environment variable > (SDL_STDIO_REDIRECT="no"). On my Linux machines, I always > set this variable, so when I run QEMU for Windows with > wine32 or wine64, stdout and stderr work. > > Printing to stdout / stderr on Windows can be an adventure: > depending on your shell (command.exe, cmd.exe, MinGW shell, > MinGW rxvt, Cygwin shell, ...) it works different, and I also > had application crashes when a GUI application which was > not started from a shell tried to print to stdout. I see it is something intentional done by SDL, but I don't think it is desirable in general. I rather doubt it would crash as that would imply that code is checking the return value of fprintf() and taking some action on error. Instead we exclusive ignore fprintf() return values, so if the OS is reporting an I/O error we'll be ignoring it. In any case, it is possible to build QEMU on Win32 without SDL, or set that env variable, at which point QEMU will be printing to stdio anyway. So in the unlikely case there is a crash scenario, we need to fix that regardless. IMHO we should be disabling this bogus behaviour of SDL so QEMU does not have different behaviour wrt stdio depending on what libraries you happen to build against, or what platform you choose. Expecting people to know about a magic env variable to make QEMU work as it does everywhere else is just broken. Regards, Daniel
On Fri, Aug 14, 2015 at 12:14:15PM +0100, Daniel P. Berrange wrote: > On Thu, Aug 13, 2015 at 07:48:47PM +0200, Stefan Weil wrote: > > Am 13.08.2015 um 14:06 schrieb Daniel P. Berrange: > > > When debugging some patches on Windows, I discovered that nothing printed > > > to stderr ever appears on the console. Eventually I discovered that if I > > > build with --disable-sdl, then stderr appears just fine. > > > > > > Looking at the code in vl.c I see a hack for SDL introduced in > > > > > > commit 59a36a2f6728081050afc6ec97d0018467999f79 > > > Author: Stefan Weil <weil@mail.berlios.de> > > > Date: Thu Jun 18 20:11:03 2009 +0200 > > > > > > Win32: Fix compilation with SDL. > > > > > > > > > If I mostly kill the hack from vl.c, and just leave a plain '#undef main' > > > then I get working console stderr once again. > > > > > > > Hi Daniel, > > > > that's a feature of SDL 1.2: stdout and stderr are by default > > redirected to files stdout.txt and stderr.txt in the executable's > > directory. > > > > This redirection can be disabled by an environment variable > > (SDL_STDIO_REDIRECT="no"). On my Linux machines, I always > > set this variable, so when I run QEMU for Windows with > > wine32 or wine64, stdout and stderr work. > > > > Printing to stdout / stderr on Windows can be an adventure: > > depending on your shell (command.exe, cmd.exe, MinGW shell, > > MinGW rxvt, Cygwin shell, ...) it works different, and I also > > had application crashes when a GUI application which was > > not started from a shell tried to print to stdout. > > I see it is something intentional done by SDL, but I don't think it is > desirable in general. I rather doubt it would crash as that would imply > that code is checking the return value of fprintf() and taking some action > on error. Instead we exclusive ignore fprintf() return values, so if the > OS is reporting an I/O error we'll be ignoring it. In any case, it is > possible to build QEMU on Win32 without SDL, or set that env variable, > at which point QEMU will be printing to stdio anyway. So in the unlikely > case there is a crash scenario, we need to fix that regardless. > > IMHO we should be disabling this bogus behaviour of SDL so QEMU does not > have different behaviour wrt stdio depending on what libraries you happen > to build against, or what platform you choose. Expecting people to know > about a magic env variable to make QEMU work as it does everywhere else > is just broken. A thought occurs to me - on Windows we actually build two copies of the emulator - qemu-system-x86_64.exe - linked to the "console" subsystem - qemu-system-x86_64w.exe - linked to the "windows" subsystem [1] With the 'windows' subsystem build it is reasonable to believe that the user will not have any console generally available to view stderr/out. So how about we make it such that when linked to the 'console' subsystem we have stdout/stderr open by default, and when linked to the 'windows' subsystem we have stdout/stderr redirected to a file (as SDL does). Except that we make this redirection to a file happen in QEMU code, so it has consistent behaviour even in non-SDL builds on Windows. Regards, Daniel [1] '-mwindows' This option is available for Cygwin and MinGW targets. It specifies that a GUI application is to be generated by instructing the linker to set the PE header subsystem type appropriately.
> On 14 Aug 2015, at 15:15, Daniel P. Berrange <berrange@redhat.com> wrote: > > On Fri, Aug 14, 2015 at 12:14:15PM +0100, Daniel P. Berrange wrote: >> On Thu, Aug 13, 2015 at 07:48:47PM +0200, Stefan Weil wrote: >>> ... that's a feature of SDL 1.2: stdout and stderr are by default >>> redirected to files stdout.txt and stderr.txt in the executable's >>> directory. >>> >>> This redirection can be disabled by an environment variable >>> (SDL_STDIO_REDIRECT="no"). On my Linux machines, I always >>> set this variable, so when I run QEMU for Windows with >>> wine32 or wine64, stdout and stderr work. in GNU ARM Eclipse QEMU I build SDL with '--disable-stdio-redirect' to prevent this annoying behaviour. regards, Liviu
diff --git a/vl.c b/vl.c index 0adbbd6..8e1481b 100644 --- a/vl.c +++ b/vl.c @@ -39,16 +39,8 @@ #endif #ifdef CONFIG_SDL -#if defined(__APPLE__) || defined(main) #include <SDL.h> -int qemu_main(int argc, char **argv, char **envp); -int main(int argc, char **argv) -{ - return qemu_main(argc, argv, NULL); -} #undef main -#define main qemu_main -#endif #endif /* CONFIG_SDL */ #ifdef CONFIG_COCOA