From 208ae0c290cdc1d74c9286942860f1a64712f95b Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Mon, 22 Jan 2007 18:31:51 +0000 Subject: [PATCH] When system() fails in Win32, report it as an exception, print the exception value in hex, and give a URL where the value can be looked-up. --- src/backend/postmaster/postmaster.c | 12 ++++++++- src/include/port/win32.h | 42 ++++++++++++++++++++++------- src/port/exec.c | 7 ++++- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index f4c424c968..474e031111 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.508 2007/01/16 13:28:56 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.509 2007/01/22 18:31:51 momjian Exp $ * * NOTES * @@ -2421,6 +2421,7 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus) (errmsg("%s (PID %d) exited with exit code %d", procname, pid, WEXITSTATUS(exitstatus)))); else if (WIFSIGNALED(exitstatus)) +#ifndef WIN32 ereport(lev, /*------ @@ -2428,6 +2429,15 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus) "server process" */ (errmsg("%s (PID %d) was terminated by signal %d", procname, pid, WTERMSIG(exitstatus)))); +#else + ereport(lev, + + /*------ + translator: %s is a noun phrase describing a child process, such as + "server process" */ + (errmsg("%s (PID %d) was terminated by exception %X\nSee http://source.winehq.org/source/include/ntstatus.h for a description\nof the hex value.", + procname, pid, WTERMSIG(exitstatus)))); +#endif else ereport(lev, diff --git a/src/include/port/win32.h b/src/include/port/win32.h index 22d71272d1..dc2219be16 100644 --- a/src/include/port/win32.h +++ b/src/include/port/win32.h @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.65 2007/01/11 02:42:31 momjian Exp $ */ +/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.66 2007/01/22 18:31:51 momjian Exp $ */ #if defined(_MSC_VER) || defined(__BORLANDC__) #define WIN32_ONLY_COMPILER @@ -115,16 +115,38 @@ int semop(int semId, struct sembuf * sops, int flag); /* * Signal stuff - * WIN32 doesn't have wait(), so the return value for children - * is simply the return value specified by the child, without - * any additional information on whether the child terminated - * on its own or via a signal. These macros are also used - * to interpret the return value of system(). + * + * For WIN32, there is no wait() call so there are no wait() macros + * to interpret the return value of system(). Instead, system() + * return values < 0x100 are used for exit() termination, and higher + * values are used to indicated non-exit() termination, which is + * similar to a unix-style signal exit (think SIGSEGV == + * STATUS_ACCESS_VIOLATION). Return values are broken up into groups: + * + * http://msdn2.microsoft.com/en-gb/library/aa489609.aspx + * + * NT_SUCCESS 0 - 0x3FFFFFFF + * NT_INFORMATION 0x40000000 - 0x7FFFFFFF + * NT_WARNING 0x80000000 - 0xBFFFFFFF + * NT_ERROR 0xC0000000 - 0xFFFFFFFF + * + * Effectively, we don't care on the severity of the return value from + * system(), we just need to know if it was because of exit() or generated + * by the system, and it seems values >= 0x100 are system-generated. + * See this URL for a list of WIN32 STATUS_* values: + * + * Wine (URL used in our error messages) - + * http://source.winehq.org/source/include/ntstatus.h + * Descriptions - http://www.comp.nus.edu.sg/~wuyongzh/my_doc/ntstatus.txt + * MS SDK - http://www.nologs.com/ntstatus.html + * + * Some day we might want to print descriptions for the most common + * exceptions, rather than printing a URL. */ -#define WEXITSTATUS(w) (w) -#define WIFEXITED(w) (true) -#define WIFSIGNALED(w) (false) -#define WTERMSIG(w) (0) +#define WIFEXITED(w) (((w) & 0xffffff00) == 0) +#define WIFSIGNALED(w) (!WIFEXITED(w)) +#define WEXITSTATUS(w) (w) +#define WTERMSIG(w) (w) #define sigmask(sig) ( 1 << ((sig)-1) ) diff --git a/src/port/exec.c b/src/port/exec.c index a8bd398460..4d54ed0e58 100644 --- a/src/port/exec.c +++ b/src/port/exec.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/exec.c,v 1.44 2007/01/05 22:20:02 momjian Exp $ + * $PostgreSQL: pgsql/src/port/exec.c,v 1.45 2007/01/22 18:31:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -582,8 +582,13 @@ pclose_check(FILE *stream) log_error(_("child process exited with exit code %d"), WEXITSTATUS(exitstatus)); else if (WIFSIGNALED(exitstatus)) +#ifndef WIN32 log_error(_("child process was terminated by signal %d"), WTERMSIG(exitstatus)); +#else + log_error(_("child process was terminated by exception %X\nSee http://source.winehq.org/source/include/ntstatus.h for a description\nof the hex value."), + WTERMSIG(exitstatus)); +#endif else log_error(_("child process exited with unrecognized status %d"), exitstatus);