When system() fails in Win32, report it as an exception, print the
authorBruce Momjian <bruce@momjian.us>
Mon, 22 Jan 2007 18:31:51 +0000 (18:31 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 22 Jan 2007 18:31:51 +0000 (18:31 +0000)
exception value in hex, and give a URL where the value can be looked-up.

src/backend/postmaster/postmaster.c
src/include/port/win32.h
src/port/exec.c

index f4c424c9680b1370e8551452a69a7c28e728aac3..474e0311112d98fbd5e70927055562d5b5518425 100644 (file)
@@ -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,
 
index 22d71272d19834abab0423fea4032ee94547ebe5..dc2219be165c50a9b9b66ac902c5dd6cb2fcfcd1 100644 (file)
@@ -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) )
 
index a8bd39846072f9b640b4f329bdcf4f8e8bd7397b..4d54ed0e589aeaa26974445163a819c3cb0462d8 100644 (file)
@@ -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);