diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 4111b87f1f..7e18251a58 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.510 2007/01/22 19:38:05 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.511 2007/01/23 01:45:11 momjian Exp $ * * NOTES * @@ -2430,14 +2430,30 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus) (errmsg("%s (PID %d) was terminated by signal %d", procname, pid, WTERMSIG(exitstatus)))); #else - ereport(lev, + { + static char last_system_error[512]; + if (WERRORCODE(exitstatus) == 0 || + FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + WERRORCODE(exitstatus), + MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), + last_system_error, + sizeof(last_system_error) - 1, + NULL) == 0) + snprintf(last_system_error, sizeof(last_system_error) - 1, + "Unknown error %X.", WEXITSTATUS(exitstatus)); + + 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", - procname, pid, WTERMSIG(exitstatus)), - errhint("See http://source.winehq.org/source/include/ntstatus.h for a description of the hex value."))); + (errmsg("%s (PID %d) was terminated by the operating system", + procname, pid), + errdetail("%s", last_system_error))); + } #endif else ereport(lev, diff --git a/src/include/port/win32.h b/src/include/port/win32.h index f88ef11a54..ef515fd48b 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.67 2007/01/22 18:32:57 momjian Exp $ */ +/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.68 2007/01/23 01:45:11 momjian Exp $ */ #if defined(_MSC_VER) || defined(__BORLANDC__) #define WIN32_ONLY_COMPILER @@ -140,13 +140,26 @@ int semop(int semId, struct sembuf * sops, int flag); * 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. + * Because FormatMessage only handles NT_ERROR strings, and assumes they + * do not have the 0xC prefix, we strip it to match this list: + * http://msdn2.microsoft.com/en-us/library/ms681381.aspx + * + * When using FormatMessage(): + * + * On MinGW, system() returns STATUS_* values. MSVC might be + * different. To test, create a binary that does *(NULL), and + * then create a second binary that calls it via system(), + * and check the return value of system(). On MinGW, it is + * 0xC0000005 == STATUS_ACCESS_VIOLATION, and 0x5 is a value + * FormatMessage() can look up. GetLastError() does not work; + * always zero. */ -#define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) -#define WIFSIGNALED(w) (!WIFEXITED(w)) -#define WEXITSTATUS(w) (w) -#define WTERMSIG(w) (w) +#define STATUS_ERROR_MASK 0xC0000000 +#define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) +#define WIFSIGNALED(w) (!WIFEXITED(w)) +#define WEXITSTATUS(w) (w) +#define WERRORCODE(w) ((((w) & STATUS_ERROR_MASK) == STATUS_ERROR_MASK) ? \ + ((w) & ~STATUS_ERROR_MASK) : 0) #define sigmask(sig) ( 1 << ((sig)-1) ) diff --git a/src/port/exec.c b/src/port/exec.c index 4d54ed0e58..0ed4b59014 100644 --- a/src/port/exec.c +++ b/src/port/exec.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/exec.c,v 1.45 2007/01/22 18:31:51 momjian Exp $ + * $PostgreSQL: pgsql/src/port/exec.c,v 1.46 2007/01/23 01:45:11 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -586,8 +586,24 @@ pclose_check(FILE *stream) 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)); + { + static char last_system_error[512]; + + if (WERRORCODE(exitstatus) == 0 || + FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + WERRORCODE(exitstatus), + MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), + last_system_error, + sizeof(last_system_error) - 1, + NULL) == 0) + snprintf(last_system_error, sizeof(last_system_error) - 1, + "Unknown error %X.", WEXITSTATUS(exitstatus)); + + log_error(_("child process was terminated by the operating system\n%s"), + last_system_error); + } #endif else log_error(_("child process exited with unrecognized status %d"),