Hi all,It is sometimes quite a pain in the neck to understand loading failures, especially when they happen on user side and we don't have access to their environment. The following patch attempts to address this issue by giving a means to get debugging information. It should certainly be refined with a means to select the verbosity level (or maybe some bitfield).
It helped me track something which I don't understand: when I dlopen a module.la which has a dependency.la library, I expected ltdl to automatically find dependency.la which is not installed. Yet it does not seem to use the module.la's deplibs to dlopen them, it delegates this to the native dlopen. As a result, since my library is not installed, dlopen fails (see dlopen-failure.txt attachement, notice the deplibs line).
Of course I can adjust LD_LIBRARY_PATH, but that's not what I expected. Cheers!
/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/tests/bin/urbi-launch: --debug --start /dev/null /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch:loaders: lt_dlopen, lt_preopen /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: loading /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: try_dlopen (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject, .la) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Parsing *.la file: /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject.la /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: *.la: dlname: libuobject.dylib /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: *.la: old_name: (null) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: *.la: deplibs: -L/opt/local/lib /Users/akim/src/urbi/2.0/kernel/_build/i386-apple-darwin9.6.0/sdk-remote/lib/libport/libport.la /Users/akim/src/urbi/2.0/kernel/_build/i386-apple-darwin9.6.0/src/lib/sched/libsched.la /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: *.la: installed: 0 /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: *.la: libdir: /usr/local/gostai/core/i386-apple-darwin9.6.0/engine /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: load_deplibs( -L/opt/local/lib /Users/akim/src/urbi/2.0/kernel/_build/i386-apple-darwin9.6.0/sdk-remote/lib/libport/libport.la /Users/akim/src/urbi/2.0/kernel/_build/i386-apple-darwin9.6.0/src/lib/sched/libsched.la): not implemented /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: tryall_dlopen (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/.libs/libuobject.dylib, (ALL)) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Calling lt_dlopen->module_open (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/.libs/libuobject.dylib) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Result: Failed /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Calling lt_preopen->module_open (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/.libs/libuobject.dylib) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Result: Failed /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: tryall_dlopen (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject.dylib, (ALL)) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Calling lt_dlopen->module_open (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject.dylib) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Result: Failed /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Calling lt_preopen->module_open (/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject.dylib) /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: ltdl: Result: Failed /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/src/.libs/urbi-launch: failed to load /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/libuobject: dlopen(/Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/.libs/libuobject.dylib, 9): Library not loaded: /usr/local/lib/libsched.dylib Referenced from: /Users/akim/src/urbi/2.0/sdk-remote/_build/i386-apple-darwin9.6.0/../src/.libs/libuobject.dylib Reason: image not found
From 25d4711a3adb68ebcc66d8d105e6f1a214e16871 Mon Sep 17 00:00:00 2001 From: Akim Demaille <demai...@gostai.com> Date: Fri, 9 Jan 2009 14:38:13 +0100 Subject: [PATCH] Provide a means to activate dynamically the debug traces. * libltdl/ltdl.h [LT_DEBUG_LOADERS] (lt_debug_level) (lt_program_name): Declare. * libltdl/ltdl.c [LT_DEBUG_LOADERS] (lt_debug_level) (lt_program_name): New. (LT_DEBUGF, LT_DEBUGF1, LT_DEBUGF2, LT_DEFAULT, LT_NONNULL): New. Use them instead of guarded fprintf. --- libltdl/lt_dlloader.c | 4 ++- libltdl/ltdl.c | 89 +++++++++++++++++++++++++++++++++++++------------ libltdl/ltdl.h | 15 +++++++-- 3 files changed, 82 insertions(+), 26 deletions(-) diff --git a/libltdl/lt_dlloader.c b/libltdl/lt_dlloader.c index 4e66a6c..90a8af1 100644 --- a/libltdl/lt_dlloader.c +++ b/libltdl/lt_dlloader.c @@ -1,6 +1,6 @@ /* lt_dlloader.c -- dynamic library loader interface - Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Gary V. Vaughan, 2004 NOTE: The canonical source of this file is maintained with the @@ -109,6 +109,8 @@ loader_dump_callback (SList *item, void *userdata) void lt_dlloader_dump (void) { + if (lt_program_name) + fprintf (stderr, "%s:", lt_program_name); fprintf (stderr, "loaders: "); if (!loaders) { diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 4da9676..6f65a0a 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -151,6 +151,37 @@ static char *user_search_path= 0; static lt_dlhandle handles = 0; static int initialized = 0; +/* --- DEBUGGING --- */ +#if defined LT_DEBUG_LOADERS +int lt_debug_level = 0; +const char* lt_program_name = 0; + +# define LT_DEBUGF(Args) \ + do { \ + if (lt_debug_level) \ + { \ + if (lt_program_name) \ + fprintf (stderr, "%s: ", lt_program_name); \ + fprintf (stderr, "ltdl: "); \ + fprintf Args; \ + fprintf (stderr, "\n"); \ + } \ + } while (0) + +#else +# define LT_DEBUGF(Args) +#endif + +#define LT_DEFAULT(Arg, Default) \ + (Arg ? Arg : Default) +#define LT_NONNULL(Arg) \ + LT_DEFAULT(Arg, "(null)") +#define LT_DEBUGF1(Format, Arg1) \ + LT_DEBUGF((stderr, Format, Arg1)) +#define LT_DEBUGF2(Format, Arg1, Arg2) \ + LT_DEBUGF((stderr, Format, Arg1, Arg2)) + + /* Our memory failure callback sets the error message to be passed back up to the client, so we must be careful to return from mallocation callers if allocation fails (as this callback returns!!). */ @@ -362,11 +393,9 @@ tryall_dlopen (lt_dlhandle *phandle, const char *filename, const char * saved_error = 0; int errors = 0; -#ifdef LT_DEBUG_LOADERS - fprintf (stderr, "tryall_dlopen (%s, %s)\n", - filename ? filename : "(null)", - vtable ? vtable->name : "(ALL)"); -#endif + LT_DEBUGF2 ("tryall_dlopen (%s, %s)", + LT_NONNULL (filename), + LT_DEFAULT (vtable, "(ALL)")); LT__GETERROR (saved_error); @@ -426,17 +455,15 @@ tryall_dlopen (lt_dlhandle *phandle, const char *filename, else loader_vtable = lt_dlloader_get (loader); -#ifdef LT_DEBUG_LOADERS - fprintf (stderr, "Calling %s->module_open (%s)\n", - (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)", - filename ? filename : "(null)"); -#endif - handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data, - filename, advise); -#ifdef LT_DEBUG_LOADERS - fprintf (stderr, " Result: %s\n", - handle->module ? "Success" : "Failed"); -#endif + LT_DEBUGF2 ("Calling %s->module_open (%s)", + ((loader_vtable && loader_vtable->name) + ? loader_vtable->name : "(null)"), + LT_NONNULL (filename)); + handle->module = + (*loader_vtable->module_open) (loader_vtable->dlloader_data, + filename, advise); + LT_DEBUGF1 (" Result: %s", + handle->module ? "Success" : "Failed"); if (handle->module != 0) { @@ -800,6 +827,7 @@ static int load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs) { handle->depcount = 0; + LT_DEBUGF1 ("load_deplibs(%s): not implemented", LT_NONNULL (deplibs)); return 0; } @@ -813,6 +841,8 @@ load_deplibs (lt_dlhandle handle, char *deplibs) char **names = 0; int errors = 0; + LT_DEBUGF1 ("load_deplibs(%s)", LT_NONNULL (deplibs)); + handle->depcount = 0; if (!deplibs) @@ -909,6 +939,7 @@ load_deplibs (lt_dlhandle handle, char *deplibs) if (!name) goto cleanup_names; + LT_DEBUGF1 ("found dependency %s", name); names[depcount++] = name; *end = save; } @@ -1023,6 +1054,10 @@ parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, size_t line_len = LT_FILENAME_MAX; char * line = MALLOC (char, line_len); +#define LT_DEBUG_FIELD(Field) \ + LT_DEBUGF1 ("*.la: " #Field ": %s", LT_NONNULL (*Field)) + + if (!line) { LT__SETERROR (FILE_NOT_FOUND); @@ -1066,6 +1101,7 @@ parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) { errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]); + LT_DEBUG_FIELD (dlname); } #undef STR_OLD_LIBRARY @@ -1074,12 +1110,14 @@ parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, sizeof (STR_OLD_LIBRARY) - 1) == 0) { errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + LT_DEBUG_FIELD (old_name); } #undef STR_LIBDIR #define STR_LIBDIR "libdir=" else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) { errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]); + LT_DEBUG_FIELD (libdir); } #undef STR_DL_DEPLIBS @@ -1088,14 +1126,17 @@ parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, sizeof (STR_DL_DEPLIBS) - 1) == 0) { errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + LT_DEBUG_FIELD (deplibs); } else if (streq (line, "installed=yes\n")) { *installed = 1; + LT_DEBUGF1 ("*.la: installed: %d", *installed); } else if (streq (line, "installed=no\n")) { *installed = 0; + LT_DEBUGF1 ("*.la: installed: %d", *installed); } #undef STR_LIBRARY_NAMES @@ -1117,11 +1158,14 @@ parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, } MEMREASSIGN (*dlname, last_libname); } + LT_DEBUG_FIELD (dlname); } if (errors) break; } +#undef LT_DEBUG_FIELD + cleanup: FREE (line); return errors; @@ -1146,11 +1190,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext, assert (phandle); assert (*phandle == 0); -#ifdef LT_DEBUG_LOADERS - fprintf (stderr, "try_dlopen (%s, %s)\n", - filename ? filename : "(null)", - ext ? ext : "(null)"); -#endif + LT_DEBUGF2 ("try_dlopen (%s, %s)", LT_NONNULL (filename), LT_NONNULL (ext)); LT__GETERROR (saved_error); @@ -1360,9 +1400,13 @@ try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext, } /* read the .la file */ + LT_DEBUGF1 ("Parsing *.la file: %s", attempt); if (parse_dotla_file(file, &dlname, &libdir, &deplibs, &old_name, &installed) != 0) - ++errors; + { + LT_DEBUGF1 ("Parsing *.la file failed: %s", attempt); + ++errors; + } fclose (file); @@ -1601,6 +1645,7 @@ lt_dlopenext (const char *filename) lt_dlhandle handle = 0; lt_dladvise advise; + LT_DEBUGF1 ("lt_dlopenext (%s)", LT_NONNULL (filename)); if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) handle = lt_dlopenadvise (filename, advise); diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index 8b516ad..4152ee7 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -1,7 +1,7 @@ /* ltdl.h -- generic dlopen functions Copyright (C) 1998-2000, 2004, 2005, - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. Written by Thomas Tanner, 1998 NOTE: The canonical source of this file is maintained with the @@ -44,6 +44,15 @@ LT_BEGIN_C_DECLS #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) +/* --- DEBUGGING --- */ +#if defined LT_DEBUG_LOADERS +/* Whether debugging messages are displayed. */ +extern int lt_debug_level; +/* Prefix to debug messages. */ +extern const char* lt_program_name; +#endif + + /* --- DYNAMIC MODULE LOADING API --- */ @@ -57,7 +66,7 @@ LT_SCOPE int lt_dlexit (void); LT_SCOPE int lt_dladdsearchdir (const char *search_dir); LT_SCOPE int lt_dlinsertsearchdir (const char *before, const char *search_dir); -LT_SCOPE int lt_dlsetsearchpath (const char *search_path); +LT_SCOPE int lt_dlsetsearchpath (const char *search_path); LT_SCOPE const char *lt_dlgetsearchpath (void); LT_SCOPE int lt_dlforeachfile ( const char *search_path, @@ -102,7 +111,7 @@ LT_SCOPE int lt_dlpreload_open (const char *originator, lt_dlpreload_callback_func *func); #define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols -#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ +#define LTDL_SET_PRELOADED_SYMBOLS() LT_STMT_START{ \ extern const lt_dlsymlist lt_preloaded_symbols[]; \ lt_dlpreload_default(lt_preloaded_symbols); \ }LT_STMT_END -- 1.6.0.4.790.gaa14a
libtool.config
Description: Binary data