OSDN Git Service

[ backpatched to 8.0.X.]
authorBruce Momjian <bruce@momjian.us>
Fri, 12 Aug 2005 21:23:10 +0000 (21:23 +0000)
committerBruce Momjian <bruce@momjian.us>
Fri, 12 Aug 2005 21:23:10 +0000 (21:23 +0000)
> >> 3) I restarted the postmaster both times. I got this error
> both times.
> >> :25: ERROR:  could not load library "C:/Program
> >> Files/PostgreSQL/8.0/lib/testtrigfuncs.dll": dynamic load error
>
> > Yes. We really need to look at fixing that error message. I had
> > forgotten it completely :-(
>
> > Bruce, you think we can sneak that in after feature freeze? I would
> > call it a bugfix :-)
>
> Me too.  That's been on the radar for awhile --- please do
> send in a patch.

Here we go, that wasn't too hard :-)

Apart from adding the error handling, it does one more thing: it changes
the errormode when loading the DLLs. Previously if a DLL was broken, or
referenced other DLLs that couldn't be found, a popup dialog box would
appear on the screen. Which had to be clicked before the backend could
continue. This patch also disables the popup error message for DLL
loads.

I think this is something we should consider doing for the entire
backend - disable those popups, and say we deal with it ourselves. What
do you other win32 hackers thinnk about this?

In the meantime, this patch fixes the error msgs. Please apply for 8.1
and please consider a backpatch to 8.0.

Magnus Hagander

src/backend/port/dynloader/win32.c

index 13471df..c2c496a 100644 (file)
@@ -1,32 +1,84 @@
-/* $PostgreSQL: pgsql/src/backend/port/dynloader/win32.c,v 1.5 2004/12/02 19:38:50 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/backend/port/dynloader/win32.c,v 1.6 2005/08/12 21:23:10 momjian Exp $ */
 
 #include <windows.h>
+#include <stdio.h>
 
 char *dlerror(void);
 int dlclose(void *handle);
 void *dlsym(void *handle, const char *symbol);
 void *dlopen(const char *path, int mode);
 
+static char last_dyn_error[512];
+
+static void set_dl_error(void)
+{
+       DWORD err = GetLastError();
+
+       if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
+                               FORMAT_MESSAGE_FROM_SYSTEM,
+                               NULL,
+                               err,
+                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                               last_dyn_error,
+                               sizeof(last_dyn_error)-1,
+                               NULL) == 0)
+       {
+               snprintf(last_dyn_error, sizeof(last_dyn_error)-1,
+                               "unknown error %lu", err);
+       }       
+}
+
 char *
 dlerror(void)
 {
-       return "dynamic load error";
+       if (last_dyn_error[0])
+               return last_dyn_error;
+       else
+               return NULL;
 }
 
 int
 dlclose(void *handle)
 {
-       return FreeLibrary((HMODULE) handle) ? 0 : 1;
+       if (!FreeLibrary((HMODULE) handle))
+       {
+               set_dl_error();
+               return 1;
+       }
+       last_dyn_error[0] = 0;
+       return 0;
 }
 
 void *
 dlsym(void *handle, const char *symbol)
 {
-       return (void *) GetProcAddress((HMODULE) handle, symbol);
+       void *ptr;
+       ptr = GetProcAddress((HMODULE) handle, symbol);
+       if (!ptr) 
+       {
+               set_dl_error();
+               return NULL;
+       }
+       last_dyn_error[0] = 0;
+       return ptr;
 }
 
 void *
 dlopen(const char *path, int mode)
 {
-       return (void *) LoadLibrary(path);
+       HMODULE h;
+       int prevmode;
+
+       /* Disable popup error messages when loading DLLs */
+       prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+       h = LoadLibrary(path);
+       SetErrorMode(prevmode);
+       
+       if (!h) 
+       {
+               set_dl_error();
+               return NULL;
+       }
+       last_dyn_error[0] = 0;
+       return (void *) h;
 }