libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: lt_dlopenext() sets error on succesful loading the library


From: Ralf Wildenhues
Subject: Re: lt_dlopenext() sets error on succesful loading the library
Date: Sun, 1 Feb 2009 19:21:11 +0100
User-agent: Mutt/1.5.18 (2008-05-17)

Hello Kurt,

first off, thanks for the bug report and patches, and sorry for the long
delay.

* Kurt Roeckx wrote on Fri, Jan 02, 2009 at 12:10:38PM CET:
> 
> There was an error report on the Debian bug tracking system
> that lt_dlopenext() sets an error on succesful loading the library
> if no extention was given.  See:
> http://bugs.debian.org/510006
> 
> Here are the patches I've made for both the 1.5 and 2.2 branch.

Before I get to the patches, I would like to have a reproducible test
case.  Here's the code I gather from the references (patch against git
master).  I've redone the build commands the way I think they are
correct (those mentioned in the Autobook are pretty bogus).

Can you be bothered to amend the test so that it exposes the bug?
Thanks.  In a configured build tree, you can run the test with
  make check-local TESTSUITEFLAGS="-v -d -x -k lt_dlopenext"

> PS: Can somebody fix the example in autobook?

Good idea.  Let's write a patch for that when we've sorted this out
here, and send it to Gary.

Cheers,
Ralf

    New test for lt_dlopenext error message.
    * tests/lt_dlopenext.at (lt_dlopenext error messages): New file,
    with new test.
    * Makefile.am: Update.
    Report against Debian from Kaiwang Chen via Kurt Roeckx.

diff --git a/Makefile.am b/Makefile.am
index 3714519..7982025 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -478,6 +478,7 @@ TESTSUITE_AT        = tests/testsuite.at \
                  tests/lt_dlexit.at \
                  tests/lt_dladvise.at \
                  tests/lt_dlopen.at \
+                 tests/lt_dlopenext.at \
                  tests/ltdl-api.at \
                  tests/need_lib_prefix.at \
                  tests/standalone.at \
diff --git a/tests/lt_dlopenext.at b/tests/lt_dlopenext.at
new file mode 100644
index 0000000..505621f
--- /dev/null
+++ b/tests/lt_dlopenext.at
@@ -0,0 +1,193 @@
+# lt_dlopenext.at -- test libltdl functionality             -*- Autotest -*-
+#
+#   Copyright (C) 2009 Free Software Foundation, Inc.
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from  http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+####
+
+AT_SETUP([lt_dlopenext error messages])
+AT_KEYWORDS([libltdl])
+
+# This code is copied from the Autobook:
+# <http://sources.redhat.com/autobook/autobook/autobook_169.html>
+# so if it needs changes, be sure to notify the Autobook authors
+# about them.
+
+AT_DATA([simple-module.c],
+[[
+#include <stdio.h>
+
+int
+run (const char *argument)
+{
+  printf ("Hello, %s!\n", argument);
+  return 0;
+}
+]])
+
+AT_DATA([ltdl-loader.c],
+[[
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef EXIT_FAILURE
+#  define EXIT_FAILURE        1
+#  define EXIT_SUCCESS        0
+#endif
+
+#include <limits.h>
+#ifndef PATH_MAX
+#  define PATH_MAX 255
+#endif
+
+#include <string.h>
+#include <ltdl.h>
+
+#ifndef MODULE_PATH_ENV
+#  define MODULE_PATH_ENV        "MODULE_PATH"
+#endif
+
+typedef int entrypoint (const char *argument);
+
+/* Save and return a copy of the dlerror() error  message,
+   since the next API call may overwrite the original. */
+static char *dlerrordup (char *errormsg);
+
+int
+main (int argc, const char *argv[])
+{
+  char *errormsg = NULL;
+  lt_dlhandle module = NULL;
+  entrypoint *run = NULL;
+  int errors = 0;
+
+  if (argc != 3)
+    {
+      fprintf (stderr, "USAGE: main MODULENAME ARGUMENT\n");
+      exit (EXIT_FAILURE);
+    }
+
+  /* Initialise libltdl. */
+  errors = lt_dlinit ();
+
+  /* Set the module search path. */
+  if (!errors)
+    {
+      const char *path = getenv (MODULE_PATH_ENV);
+
+      if (path != NULL)
+        errors = lt_dlsetsearchpath (path);
+    }
+
+  /* Load the module. */
+  if (!errors)
+    module = lt_dlopenext (argv[1]);
+
+  /* Find the entry point. */
+  if (module)
+    {
+      run = (entrypoint *) lt_dlsym (module, "run");
+
+      /* In principle, run might legitimately be NULL, so
+         I don't use run == NULL as an error indicator
+         in general. */
+      errormsg = dlerrordup (errormsg);
+      if (errormsg != NULL)
+        {
+          errors = lt_dlclose (module);
+          module = NULL;
+        }
+    }
+  else
+    errors = 1;
+
+  /* Call the entry point function. */
+  if (!errors)
+    {
+      int result = (*run) (argv[2]);
+      if (result < 0)
+        errormsg = strdup ("module entry point execution failed");
+      else
+        printf ("\t=> %d\n", result);
+    }
+
+  /* Unload the module, now that we are done with it. */
+  if (!errors)
+    errors = lt_dlclose (module);
+
+  if (errors)
+    {
+      /* Diagnose the encountered error. */
+      errormsg = dlerrordup (errormsg);
+
+      if (!errormsg)
+        {
+          fprintf (stderr, "%s: dlerror() failed.\n", argv[0]);
+          return EXIT_FAILURE;
+        }
+    }
+
+  /* Finished with ltdl now. */
+  if (!errors)
+    if (lt_dlexit () != 0)
+      errormsg = dlerrordup (errormsg);
+
+  if (errormsg)
+    {
+      fprintf (stderr, "%s: %s.\n", argv[0], errormsg);
+      free (errormsg);
+      exit (EXIT_FAILURE);
+    }
+
+  return EXIT_SUCCESS;
+}
+
+/* Be careful to save a copy of the error message,
+   since the  next API call may overwrite the original. */
+static char *
+dlerrordup (char *errormsg)
+{
+  char *error = (char *) lt_dlerror ();
+  if (error && !errormsg)
+    errormsg = strdup (error);
+  return errormsg;
+}
+]])
+
+: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
+: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
+
+CPPFLAGS="$LTDLINCL $CPPFLAGS"
+LDFLAGS="$LDFLAGS -no-undefined"
+inst=`pwd`/inst
+libdir=$inst/lib
+
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c simple-module.c],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o simple-module.la ]dnl
+        [simple-module.lo -rpath $libdir -module -avoid-version],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c ltdl-loader.c],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o ltdl-loader$EXEEXT ]dnl
+        [ltdl-loader.$OBJEXT -dlopen self $LIBLTDL],
+        [], [ignore], [ignore])
+LT_AT_EXEC_CHECK([./ltdl-loader], [], [stdout], [ignore],
+                [simple-module World])
+AT_CHECK([grep "Hello, World" stdout], [], [ignore])
+
+AT_CLEANUP




reply via email to

[Prev in Thread] Current Thread [Next in Thread]