* autoload.cc (RETRY_COUNT): New define.
(std_dll_init): Restructure loop to retry loading a DLL only if specific errors occur. If these errors persist, try to load DLL with name only.
This commit is contained in:
parent
23dbdc2aaa
commit
0dcfb061cf
|
@ -1,3 +1,10 @@
|
||||||
|
2010-12-09 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (RETRY_COUNT): New define.
|
||||||
|
(std_dll_init): Restructure loop to retry loading a DLL only if
|
||||||
|
specific errors occur. If these errors persist, try to load DLL
|
||||||
|
with name only.
|
||||||
|
|
||||||
2010-12-08 Corinna Vinschen <corinna@vinschen.de>
|
2010-12-08 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/strings.h: Remove in favor of equivalent newlib file.
|
* include/strings.h: Remove in favor of equivalent newlib file.
|
||||||
|
|
|
@ -204,6 +204,8 @@ union retchain
|
||||||
long long ll;
|
long long ll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RETRY_COUNT 10
|
||||||
|
|
||||||
/* The standard DLL initialization routine. */
|
/* The standard DLL initialization routine. */
|
||||||
__attribute__ ((used, noinline)) static long long
|
__attribute__ ((used, noinline)) static long long
|
||||||
std_dll_init ()
|
std_dll_init ()
|
||||||
|
@ -221,27 +223,43 @@ std_dll_init ()
|
||||||
while (InterlockedIncrement (&dll->here));
|
while (InterlockedIncrement (&dll->here));
|
||||||
else if (!dll->handle)
|
else if (!dll->handle)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
|
||||||
fenv_t fpuenv;
|
fenv_t fpuenv;
|
||||||
fegetenv (&fpuenv);
|
fegetenv (&fpuenv);
|
||||||
WCHAR dll_path[MAX_PATH];
|
WCHAR dll_path[MAX_PATH];
|
||||||
|
DWORD err = ERROR_SUCCESS;
|
||||||
/* http://www.microsoft.com/technet/security/advisory/2269637.mspx */
|
/* http://www.microsoft.com/technet/security/advisory/2269637.mspx */
|
||||||
wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name);
|
wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name);
|
||||||
dll->handle = NULL;
|
|
||||||
/* MSDN seems to imply that LoadLibrary can fail mysteriously, so,
|
/* MSDN seems to imply that LoadLibrary can fail mysteriously, so,
|
||||||
since there have been reports of this in the mailing list, retry
|
since there have been reports of this in the mailing list, retry
|
||||||
several times before giving up. */
|
several times before giving up. */
|
||||||
for (int i = 1; !dll->handle && i <= 5; i++)
|
for (int i = 1; i <= RETRY_COUNT; i++)
|
||||||
if ((h = LoadLibraryW (dll_path)) != NULL)
|
{
|
||||||
dll->handle = h;
|
/* If loading the library succeeds, just leave the loop. */
|
||||||
/* FIXME: This isn't quite right. Probably should check for specific
|
if ((dll->handle = LoadLibraryW (dll_path)) != NULL)
|
||||||
error codes. */
|
break;
|
||||||
|
/* Otherwise check error code returned by LoadLibrary. If the
|
||||||
|
error code is neither NOACCESS nor DLL_INIT_FAILED, break out
|
||||||
|
of the loop. */
|
||||||
|
err = GetLastError ();
|
||||||
|
if (err != ERROR_NOACCESS && err != ERROR_DLL_INIT_FAILED)
|
||||||
|
break;
|
||||||
|
if (i < RETRY_COUNT)
|
||||||
|
yield ();
|
||||||
|
}
|
||||||
|
if (!dll->handle)
|
||||||
|
{
|
||||||
|
/* If LoadLibrary with full path returns one of the weird errors
|
||||||
|
reported on the Cygwin mailing list, retry with only the DLL
|
||||||
|
name. Checking the error codes allows to restrict loading
|
||||||
|
with just the DLL name to this specific problem. */
|
||||||
|
if ((err == ERROR_NOACCESS || err == ERROR_DLL_INIT_FAILED)
|
||||||
|
&& (dll->handle = LoadLibraryW (dll->name)) != NULL)
|
||||||
|
;
|
||||||
else if ((func->decoration & 1))
|
else if ((func->decoration & 1))
|
||||||
dll->handle = INVALID_HANDLE_VALUE;
|
dll->handle = INVALID_HANDLE_VALUE;
|
||||||
else if (i < 5)
|
|
||||||
yield ();
|
|
||||||
else
|
else
|
||||||
api_fatal ("could not load %W, %E", dll_path);
|
api_fatal ("could not load %W, %E", dll_path);
|
||||||
|
}
|
||||||
fesetenv (&fpuenv);
|
fesetenv (&fpuenv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue