Merge branch 'dynlib-simplify'

Enhance wxDynamicLibrary error logging and simplify code by not checking
for dlopen() and dlerror() that are always available nowadays.

See https://github.com/wxWidgets/wxWidgets/pull/1849
This commit is contained in:
Vadim Zeitlin
2020-05-21 02:13:10 +02:00
11 changed files with 43 additions and 231 deletions

View File

@@ -614,10 +614,7 @@ set(CMAKE_REQUIRED_LIBRARIES dl)
check_symbol_exists(dlopen dlfcn.h HAVE_DLOPEN)
cmake_pop_check_state()
if(HAVE_DLOPEN)
check_symbol_exists(dlerror dlfcn.h HAVE_DLERROR)
check_symbol_exists(dladdr dlfcn.h HAVE_DLADDR)
else()
check_symbol_exists(shl_load dl.h HAVE_SHL_LOAD)
endif()
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)

View File

@@ -984,9 +984,6 @@
/* Define if you have pthread_attr_setstacksize */
#cmakedefine HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
/* Define if you have shl_load() */
#cmakedefine HAVE_SHL_LOAD 1
/* Define if you have snprintf() */
#cmakedefine HAVE_SNPRINTF 1
@@ -1089,9 +1086,6 @@
/* Define if wchar_t is distinct type in your compiler. */
#cmakedefine wxWCHAR_T_IS_REAL_TYPE 1
/* Define if you have the dlerror function. */
#cmakedefine HAVE_DLERROR 1
/* Define if you have the dladdr function. */
#cmakedefine HAVE_DLADDR 1

121
configure vendored
View File

@@ -32736,70 +32736,6 @@ if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
HAVE_DL_FUNCS=1
DL_LINK="-ldl $DL_LINK"
else
for ac_func in shl_load
do :
ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
if test "x$ac_cv_func_shl_load" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_SHL_LOAD 1
_ACEOF
$as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h
HAVE_SHL_FUNCS=1
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld in -lshl_load" >&5
$as_echo_n "checking for dld in -lshl_load... " >&6; }
if ${ac_cv_lib_shl_load_dld+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lshl_load $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char dld ();
int
main ()
{
return dld ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_shl_load_dld=yes
else
ac_cv_lib_shl_load_dld=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_shl_load_dld" >&5
$as_echo "$ac_cv_lib_shl_load_dld" >&6; }
if test "x$ac_cv_lib_shl_load_dld" = xyes; then :
HAVE_SHL_FUNCS=1
DL_LINK="-ldld $DL_LINK"
fi
fi
done
fi
@@ -32808,63 +32744,6 @@ done
if test "$HAVE_DL_FUNCS" = 1; then
for ac_func in dlerror
do :
ac_fn_c_check_func "$LINENO" "dlerror" "ac_cv_func_dlerror"
if test "x$ac_cv_func_dlerror" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_DLERROR 1
_ACEOF
$as_echo "#define HAVE_DLERROR 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlerror in -ldl" >&5
$as_echo_n "checking for dlerror in -ldl... " >&6; }
if ${ac_cv_lib_dl_dlerror+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char dlerror ();
int
main ()
{
return dlerror ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_dl_dlerror=yes
else
ac_cv_lib_dl_dlerror=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlerror" >&5
$as_echo "$ac_cv_lib_dl_dlerror" >&6; }
if test "x$ac_cv_lib_dl_dlerror" = xyes; then :
$as_echo "#define HAVE_DLERROR 1" >>confdefs.h
fi
fi
done
for ac_func in dladdr
do :
ac_fn_c_check_func "$LINENO" "dladdr" "ac_cv_func_dladdr"

View File

@@ -5385,31 +5385,11 @@ if test "$TOOLKIT" != "MSW"; then
AC_DEFINE(HAVE_DLOPEN)
HAVE_DL_FUNCS=1
DL_LINK="-ldl $DL_LINK"
],
[
AC_CHECK_FUNCS(shl_load,
[
AC_DEFINE(HAVE_SHL_LOAD)
HAVE_SHL_FUNCS=1
],
[
AC_CHECK_LIB(shl_load, dld,
[
HAVE_SHL_FUNCS=1
DL_LINK="-ldld $DL_LINK"
])
])
])
])
dnl check also for dlerror()
if test "$HAVE_DL_FUNCS" = 1; then
AC_CHECK_FUNCS(dlerror,
AC_DEFINE(HAVE_DLERROR),
[
AC_CHECK_LIB(dl, dlerror, AC_DEFINE(HAVE_DLERROR))
]
)
AC_CHECK_FUNCS(dladdr,
AC_DEFINE(HAVE_DLADDR),
[

View File

@@ -29,9 +29,6 @@ class WXDLLIMPEXP_FWD_BASE wxDynamicLibraryDetailsCreator;
#elif defined(HAVE_DLOPEN)
#include <dlfcn.h>
typedef void *wxDllType;
#elif defined(HAVE_SHL_LOAD)
#include <dl.h>
typedef shl_t wxDllType;
#elif defined(__WXMAC__)
#include <CodeFragments.h>
typedef CFragConnectionID wxDllType;
@@ -357,11 +354,9 @@ protected:
// common part of GetSymbol() and HasSymbol()
void* DoGetSymbol(const wxString& name, bool* success = NULL) const;
#ifdef HAVE_DLERROR
// log the error after a dlxxx() function failure
static void Error();
#endif // HAVE_DLERROR
// log the error after an OS dynamic library function failure
static void ReportError(const wxString& msg,
const wxString& name = wxString());
// the handle to DLL or NULL
wxDllType m_handle;

View File

@@ -87,7 +87,6 @@
#define SIZEOF_LONG_LONG 8
#define wxSIZE_T_IS_ULONG 1
#define wxWCHAR_T_IS_REAL_TYPE 1
#define HAVE_DLERROR 1
#define HAVE_FCNTL 1
#define HAVE_GETHOSTBYNAME 1
#define HAVE_GETSERVBYNAME 1

View File

@@ -984,9 +984,6 @@
/* Define if you have pthread_attr_setstacksize */
#undef HAVE_PTHREAD_ATTR_SETSTACKSIZE
/* Define if you have shl_load() */
#undef HAVE_SHL_LOAD
/* Define if you have snprintf() */
#undef HAVE_SNPRINTF
@@ -1089,9 +1086,6 @@
/* Define if wchar_t is distinct type in your compiler. */
#undef wxWCHAR_T_IS_REAL_TYPE
/* Define if you have the dlerror function. */
#undef HAVE_DLERROR
/* Define if you have the dladdr function. */
#undef HAVE_DLADDR

View File

@@ -1076,9 +1076,6 @@ typedef pid_t GPid;
#undef HAVE_SETENV
#endif
/* Define if you have shl_load() */
#undef HAVE_SHL_LOAD
#if __CRTL_VER >= 70312000
/* Define if you have snprintf() */
#define HAVE_SNPRINTF 1
@@ -1197,9 +1194,6 @@ typedef pid_t GPid;
/* Define if wchar_t is distinct type in your compiler. */
#define wxWCHAR_T_IS_REAL_TYPE 1
/* Define if you have the dlerror function. */
#define HAVE_DLERROR 1
/* Define if you have the dladdr function. */
#undef HAVE_DLADDR

View File

@@ -86,11 +86,7 @@ bool wxDynamicLibrary::Load(const wxString& libnameOrig, int flags)
if ( m_handle == 0 && !(flags & wxDL_QUIET) )
{
#ifdef HAVE_DLERROR
Error();
#else
wxLogSysError(_("Failed to load shared library '%s'"), libname.c_str());
#endif
ReportError(_("Failed to load shared library '%s'"), libname);
}
return IsLoaded();
@@ -114,12 +110,7 @@ void *wxDynamicLibrary::GetSymbol(const wxString& name, bool *success) const
void *symbol = DoGetSymbol(name, success);
if ( !symbol )
{
#ifdef HAVE_DLERROR
Error();
#else
wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
name.c_str());
#endif
ReportError(_("Couldn't find symbol '%s' in a dynamic library"), name);
}
return symbol;

View File

@@ -145,6 +145,31 @@ wxDllType wxDynamicLibrary::GetProgramHandle()
return (wxDllType)::GetModuleHandle(NULL);
}
// ----------------------------------------------------------------------------
// error handling
// ----------------------------------------------------------------------------
/* static */
void wxDynamicLibrary::ReportError(const wxString& message, const wxString& name)
{
wxString msg(message);
if ( name.IsEmpty() && msg.Find("%s") == wxNOT_FOUND )
msg += "%s";
// msg needs a %s for the name
wxASSERT(msg.Find("%s") != wxNOT_FOUND);
const unsigned long code = wxSysErrorCode();
wxString errMsg = wxSysErrorMsgStr(code);
// The error message (specifically code==193) may contain a
// placeholder '%1' which stands for the filename.
errMsg.Replace("%1", name, false);
// Mimic the output of wxLogSysError(), but use our pre-processed
// errMsg.
wxLogError(msg + " " + _("(error %d: %s)"), name, code, errMsg);
}
// ----------------------------------------------------------------------------
// loading/unloading DLLs
// ----------------------------------------------------------------------------

View File

@@ -50,9 +50,7 @@
#endif
#if defined(HAVE_DLOPEN)
#define USE_POSIX_DL_FUNCS
#elif !defined(HAVE_SHL_LOAD)
#ifndef HAVE_DLOPEN
#error "Don't know how to load dynamic libraries on this platform!"
#endif
@@ -66,11 +64,7 @@
wxDllType wxDynamicLibrary::GetProgramHandle()
{
#ifdef USE_POSIX_DL_FUNCS
return dlopen(0, RTLD_LAZY);
#else
return PROG_HANDLE;
#endif
}
/* static */
@@ -79,7 +73,6 @@ wxDllType wxDynamicLibrary::RawLoad(const wxString& libname, int flags)
wxASSERT_MSG( !(flags & wxDL_NOW) || !(flags & wxDL_LAZY),
wxT("wxDL_LAZY and wxDL_NOW are mutually exclusive.") );
#ifdef USE_POSIX_DL_FUNCS
// we need to use either RTLD_NOW or RTLD_LAZY because if we call dlopen()
// with flags == 0 recent versions of glibc just fail the call, so use
// RTLD_NOW even if wxDL_NOW was not specified
@@ -89,54 +82,21 @@ wxDllType wxDynamicLibrary::RawLoad(const wxString& libname, int flags)
rtldFlags |= RTLD_GLOBAL;
return dlopen(libname.fn_str(), rtldFlags);
#else // !USE_POSIX_DL_FUNCS
int shlFlags = 0;
if ( flags & wxDL_LAZY )
{
shlFlags |= BIND_DEFERRED;
}
else if ( flags & wxDL_NOW )
{
shlFlags |= BIND_IMMEDIATE;
}
return shl_load(libname.fn_str(), shlFlags, 0);
#endif // USE_POSIX_DL_FUNCS/!USE_POSIX_DL_FUNCS
}
/* static */
void wxDynamicLibrary::Unload(wxDllType handle)
{
#ifdef HAVE_DLERROR
int rc =
#endif
int rc = dlclose(handle);
#ifdef USE_POSIX_DL_FUNCS
dlclose(handle);
#else // !USE_POSIX_DL_FUNCS
shl_unload(handle);
#endif // USE_POSIX_DL_FUNCS/!USE_POSIX_DL_FUNCS
#if defined(USE_POSIX_DL_FUNCS) && defined(HAVE_DLERROR)
if ( rc != 0 )
Error();
#endif
ReportError(_("Failed to unload shared library"));
}
/* static */
void *wxDynamicLibrary::RawGetSymbol(wxDllType handle, const wxString& name)
{
void *symbol;
#ifdef USE_POSIX_DL_FUNCS
symbol = dlsym(handle, name.fn_str());
#else // !USE_POSIX_DL_FUNCS
// note that shl_findsym modifies the handle argument to indicate where the
// symbol was found, but it's ok to modify the local handle copy here
if ( shl_findsym(&handle, name.fn_str(), TYPE_UNDEFINED, &symbol) != 0 )
symbol = 0;
#endif // USE_POSIX_DL_FUNCS/!USE_POSIX_DL_FUNCS
void *symbol = dlsym(handle, name.fn_str());
return symbol;
}
@@ -145,20 +105,24 @@ void *wxDynamicLibrary::RawGetSymbol(wxDllType handle, const wxString& name)
// error handling
// ----------------------------------------------------------------------------
#ifdef HAVE_DLERROR
/* static */
void wxDynamicLibrary::Error()
void wxDynamicLibrary::ReportError(const wxString& message,
const wxString& name)
{
wxString msg(message);
if ( name.IsEmpty() && msg.Find("%s") == wxNOT_FOUND )
msg += "%s";
// msg needs a %s for the name
wxASSERT(msg.Find("%s") != wxNOT_FOUND);
wxString err(dlerror());
if ( err.empty() )
err = _("Unknown dynamic library error");
wxLogError(wxT("%s"), err);
wxLogError(msg + wxT(": %s"), name, err);
}
#endif // HAVE_DLERROR
// ----------------------------------------------------------------------------
// listing loaded modules