POSIX: Show errormessage if loading a (Mod) .so failed, refs #318

.. but only if the file exists.
It's ok if mods don't have their own DLL/.so, but if they do have one
and loading fails it's interesting why they failed (e.g. no access
rights, 64bit lib with 32bit executable or other way around, missing
symbols due to wrong libc version, ...)

The same should be done for Windows, but that's still TODO.
This commit is contained in:
Daniel Gibson 2020-11-30 02:49:27 +01:00
parent 117f0948e4
commit 430a8f5e95
2 changed files with 25 additions and 1 deletions

View file

@ -268,7 +268,28 @@ TODO: OSX - use the native API instead? NSModule
================= =================
*/ */
uintptr_t Sys_DLL_Load( const char *path ) { uintptr_t Sys_DLL_Load( const char *path ) {
return (uintptr_t)dlopen( path, RTLD_NOW ); void* ret = dlopen( path, RTLD_NOW );
if (ret == NULL) {
// dlopen() failed - this might be ok (we tried one possible path and the next will work)
// or it might be worth warning about (the lib existed but still couldn't be loaded,
// maybe a missing symbol or permission problems)
// unfortunately we only get a string from dlerror(), not some distinctive error code..
// so use try to open() the file to get a better idea what went wrong
int fd = open(path, O_RDONLY);
if (fd < 0) { // couldn't open file for reading either
int e = errno;
if(e != ENOENT) {
// it didn't fail because the file doesn't exist - log it, might be interesting (=> likely permission problem)
common->Warning("Failed to load lib '%s'! Reason: %s ( %s )\n", path, dlerror(), strerror(e));
}
} else {
// file could be opened, so it exists => log just dlerror()
close(fd);
common->Warning("Failed to load lib '%s' even though it exists and is readable! Reason: %s\n", path, dlerror());
}
}
return (uintptr_t)ret;
} }
/* /*

View file

@ -600,6 +600,9 @@ uintptr_t Sys_DLL_Load( const char *dllName ) {
Sys_DLL_Unload( (uintptr_t)libHandle ); Sys_DLL_Unload( (uintptr_t)libHandle );
return 0; return 0;
} }
} else {
DWORD e = GetLastError();
// TODO
} }
return (uintptr_t)libHandle; return (uintptr_t)libHandle;
} }