]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
sys: write significant engine and QC errors to stderr
authorbones_was_here <bones_was_here@xonotic.au>
Thu, 4 Jan 2024 14:41:43 +0000 (00:41 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Fri, 5 Jan 2024 05:35:02 +0000 (15:35 +1000)
A server configured with -nostdout or sys_stdout 0 will now be able to
report bugs.

Retrieves stdio stream FDs instead of assuming they're always 0,1,2.
Fixes some comment!=code discrepancies.

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
host.c
prvm_cmds.c
prvm_exec.c
sys_shared.c

diff --git a/host.c b/host.c
index 424b0729c56f8307ccf2c784cd7e0d53a0c7ee29..2bfd6912c239084b2645b0b8a13b9beec4dd6670 100644 (file)
--- a/host.c
+++ b/host.c
@@ -89,6 +89,10 @@ void Host_Error (const char *error, ...)
        static char hosterrorstring2[MAX_INPUTLINE]; // THREAD UNSAFE
        static qbool hosterror = false;
        va_list argptr;
+       int outfd = sys.outfd;
+
+       // set output to stderr
+       sys.outfd = fileno(stderr);
 
        // turn off rcon redirect if it was active when the crash occurred
        // to prevent loops when it is a networking problem
@@ -141,6 +145,9 @@ void Host_Error (const char *error, ...)
 
        hosterror = false;
 
+       // restore configured outfd
+       sys.outfd = outfd;
+
        Host_AbortCurrentFrame();
 }
 
index 0d281e62ce7f9672edcd6da82f0a6bb5af5c56c2..2812f2c29dc106e3d69c7f4b05d57413973c509f 100644 (file)
@@ -27,6 +27,10 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
        va_list argptr;
        char msg[MAX_INPUTLINE];
        static double recursive = -1;
+       int outfd = sys.outfd;
+
+       // set output to stderr
+       sys.outfd = fileno(stderr);
 
        va_start(argptr,fmt);
        dpvsnprintf(msg,sizeof(msg),fmt,argptr);
@@ -41,6 +45,9 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
                PRVM_PrintState(prog, 0);
                recursive = -1;
        }
+
+       // restore configured outfd
+       sys.outfd = outfd;
 }
 
 
index fd0ff40b9f5fe802adea919a93cc0e288c68a419..af71b3020e5cd76404902cb953c1a42e302a2b26 100644 (file)
@@ -715,6 +715,7 @@ extern cvar_t prvm_errordump;
 void PRVM_Crash(prvm_prog_t *prog)
 {
        char vabuf[1024];
+       int outfd = sys.outfd;
 
        cl.csqc_loaded = false;
 
@@ -723,6 +724,9 @@ void PRVM_Crash(prvm_prog_t *prog)
        if (!prog->loaded)
                return;
 
+       // set output to stderr
+       sys.outfd = fileno(stderr);
+
        PRVM_serverfunction(SV_Shutdown) = 0; // don't call SV_Shutdown on crash
 
        if( prog->depth > 0 )
@@ -746,6 +750,9 @@ void PRVM_Crash(prvm_prog_t *prog)
 
        // reset the prog pointer
        prog = NULL;
+
+       // restore configured outfd
+       sys.outfd = outfd;
 }
 
 /*
index 78bb56e3914eaf38cbbe5ae016b6c53f02e4d06d..6cfe9213cded7209365dadec923b7598a7bdf62e 100644 (file)
@@ -71,10 +71,13 @@ void Sys_Quit (int returnvalue)
 #ifdef __ANDROID__
        Sys_AllowProfiling(false);
 #endif
+
 #ifndef WIN32
-       fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK);
+       fcntl(fileno(stdout), F_SETFL, fcntl(fileno(stdout), F_GETFL, 0) & ~O_NONBLOCK);
+       fcntl(fileno(stderr), F_SETFL, fcntl(fileno(stderr), F_GETFL, 0) & ~O_NONBLOCK);
 #endif
        fflush(stdout);
+       fflush(stderr);
 
        exit(returnvalue);
 }
@@ -700,9 +703,10 @@ void Sys_Error (const char *error, ...)
        va_list argptr;
        char string[MAX_INPUTLINE];
 
-// change stdin to non blocking
+       // set output to blocking stderr
+       sys.outfd = fileno(stderr);
 #ifndef WIN32
-       fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK);
+       fcntl(sys.outfd, F_SETFL, fcntl(sys.outfd, F_GETFL, 0) & ~O_NONBLOCK);
 #endif
 
        va_start (argptr,error);
@@ -716,6 +720,8 @@ void Sys_Error (const char *error, ...)
 
        Sys_SDL_Dialog("Engine Error", string);
 
+       fflush(stderr);
+
        exit (1);
 }
 
@@ -941,10 +947,16 @@ static void Sys_HandleCrash(int sig)
                default:      sigdesc = "Yo dawg, we hit a bug while hitting a bug";
        }
 
+       // set output to blocking stderr
+       sys.outfd = fileno(stderr);
+#ifndef WIN32
+       fcntl(sys.outfd, F_SETFL, fcntl(sys.outfd, F_GETFL, 0) & ~O_NONBLOCK);
+#endif
+
        fprintf(stderr, "\n\n\e[1;37;41m    Engine Crash: %s (%d)    \e[m\n", sigdesc, sig);
 #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
        // the first two addresses will be in this function and in signal() in libc
-       backtrace_symbols_fd(stackframes + 2, framecount - 2, fileno(stderr));
+       backtrace_symbols_fd(stackframes + 2, framecount - 2, sys.outfd);
 #endif
        fprintf(stderr, "\e[1m%s\e[m\n", engineversion);
 
@@ -956,6 +968,8 @@ static void Sys_HandleCrash(int sig)
 
        Sys_SDL_Dialog("Engine Crash", sigdesc);
 
+       fflush(stderr);
+
        exit (sig);
 }