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




Attachment: libtool.config
Description: Binary data


Reply via email to