libtool-patches
[Top][All Lists]
Advanced

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

Re: libtool, llvm-gcc, failing C++ exceptions


From: Ralf Wildenhues
Subject: Re: libtool, llvm-gcc, failing C++ exceptions
Date: Sat, 9 Jan 2010 19:23:48 +0100
User-agent: Mutt/1.5.20 (2009-10-28)

[ moving from libtool@ ]

> * Bob Friesenhahn wrote on Tue, Jan 05, 2010 at 05:11:56PM CET:
> > Using 'llvm-gcc' (GCC frontend to llvm compiler) I find that C++
> > exceptions do not work (are not caught) in the built programs.
[ and suspect libtool as culprit ]

We can only find out better if we have small examples to look at.
Here is a proposed patch to try exception handling in libraries and
modules.  Tested with g++ on GNU/Linux; it will certainly need fixes
for other systems, and Libtool may as well.

I'd appreciate a look over it for any obvious glitches, before I commit
it.

Thanks,
Ralf

    Testsuite exposure for C++ exception handling.
    
    * tests/exceptions.at (C++ exception handling): New file, new
    test.
    * Makefile.am (TESTSUITE_AT): Update.
    Report by Bob Friesenhahn.

diff --git a/Makefile.am b/Makefile.am
index 31b4275..e9f8566 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -496,6 +496,7 @@ TESTSUITE_AT        = tests/testsuite.at \
                  tests/recursive.at \
                  tests/template.at \
                  tests/ctor.at \
+                 tests/exceptions.at \
                  tests/early-libtool.at \
                  tests/no-executables.at \
                  tests/deplibs-ident.at \
diff --git a/tests/exceptions.at b/tests/exceptions.at
new file mode 100644
index 0000000..d551cb8
--- /dev/null
+++ b/tests/exceptions.at
@@ -0,0 +1,231 @@
+# exception.at -- test C++ exception handling with libtool  -*- Autotest -*-
+#
+#   Copyright (C) 2010 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([C++ exception handling])
+AT_KEYWORDS([libtool])
+AT_KEYWORDS([libltdl])
+: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
+: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
+CPPFLAGS="$LTDLINCL $CPPFLAGS"
+
+AT_DATA([module.h],
+[[class modexc { };
+extern "C" int modfoo () throw (modexc);
+]])
+
+AT_DATA([module.cpp],
+[[#include <iostream>
+#include "module.h"
+
+int modbar (void) throw (modexc)
+{
+  throw modexc ();
+}
+
+extern "C"
+int modfoo (void) throw (modexc)
+{
+  try {
+    modbar ();
+  }
+  catch (modexc) {
+    std::cerr << "caught inside module\n";
+    throw modexc ();
+  }
+  return 0;
+}
+]])
+
+AT_DATA([lib.h],
+[[class libexc { };
+int libfoo () throw (libexc);
+]])
+
+AT_DATA([lib.cpp],
+[[#include <iostream>
+#include "lib.h"
+
+int libbar (void) throw (libexc)
+{
+  throw libexc ();
+}
+
+int libfoo (void) throw (libexc)
+{
+  try {
+    libbar ();
+  }
+  catch (libexc) {
+    std::cerr << "caught inside lib\n";
+    throw libexc ();
+  }
+  return 0;
+}
+]])
+
+AT_DATA([main.cpp],
+[[#include <ltdl.h>
+#include <cstdlib>
+#include <iostream>
+#include "lib.h"
+#include "module.h"
+
+class exc { };
+
+int foo (void) throw (exc)
+{
+  throw exc ();
+  return 0;
+}
+
+int exceptions_in_prog (void)
+{
+  std::cerr << "exceptions_in_prog\n";
+  try {
+    foo ();
+  }
+  catch (exc) {
+     std::cerr << "caught\n";
+    return 0;
+  }
+  return 1;
+}
+
+int exceptions_in_lib (void)
+{
+  std::cerr << "exceptions_in_lib\n";
+  try {
+    libfoo ();
+  }
+  catch (libexc) {
+     std::cerr << "caught\n";
+    return 0;
+  }
+  return 1;
+}
+
+int exceptions_in_module (void)
+{
+  std::cerr << "exceptions_in_module\n";
+
+  if (lt_dlinit ())
+    {
+      std::cerr << "init error: " << lt_dlerror () << '\n';
+      return 1;
+    }
+
+  // Some systems need RTLD_GLOBAL for exceptions to work in modules.
+  lt_dladvise advise;
+  if (lt_dladvise_init (&advise) || lt_dladvise_global (&advise))
+    {
+      std::cerr << "error setting advise global\n";
+      return 1;
+    }
+
+  lt_dlhandle handle = lt_dlopenadvise ("module.la", advise);
+  if (handle == NULL)
+    {
+      std::cerr << "dlopen failed: " << lt_dlerror () << '\n';
+      return 1;
+    }
+  lt_dladvise_destroy (&advise);
+
+  typedef int (*pfun) (void);
+  pfun pf = (pfun) lt_dlsym (handle, "modfoo");
+  if (pf == NULL)
+    {
+      std::cerr << "dlsym failed: " << lt_dlerror () << '\n';
+      return 1;
+    }
+
+  try {
+    (*pf) ();
+  }
+  catch (modexc) {
+    if (lt_dlclose (handle))
+      {
+        std::cerr << "dlclose failed: " << lt_dlerror () << '\n';
+       return 1;
+      }
+    if (lt_dlexit ())
+      {
+        std::cerr << "lt_dlexit failed: " << lt_dlerror () << '\n';
+       return 1;
+      }
+    return 0;
+  }
+  return 1;
+}
+
+int main (void)
+{
+  if (exceptions_in_prog ())
+    return 1;
+  if (exceptions_in_lib ())
+    return 1;
+  if (exceptions_in_module ())
+    return 1;
+  return 0;
+}
+]])
+
+inst=`pwd`/inst
+libdir=$inst/lib
+bindir=$inst/bin
+moddir=$inst/mod
+mkdir l m $inst $libdir $bindir $moddir
+
+# If the C++ compiler isn't capable, don't bother.
+AT_CHECK([$CXX $CPPFLAGS $CXXFLAGS -c main.cpp || exit 77], [], [ignore], 
[ignore])
+
+for file in lib.cpp module.cpp; do
+  AT_CHECK([$LIBTOOL --mode=compile --tag=CXX $CXX $CPPFLAGS $CXXFLAGS -c 
$file],
+          [], [ignore], [ignore])
+done
+AT_CHECK([$LIBTOOL --mode=link --tag=CXX $CXX $CXXFLAGS $LDFLAGS -o l/liba.la 
]dnl
+        [lib.lo -no-undefined -version-info 1:0:0 -rpath $libdir],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link --tag=CXX $CXX $CXXFLAGS $LDFLAGS -o 
m/module.la ]dnl
+        [module.lo -module -avoid-version -no-undefined -rpath $moddir],
+        [], [ignore], [ignore])
+
+# We need -export-dynamic for the exception handling in modules to work.
+AT_CHECK([$LIBTOOL --mode=link --tag=CXX $CXX $CXXFLAGS $LDFLAGS -o 
main$EXEEXT ]dnl
+        [main.$OBJEXT l/liba.la -dlopen m/module.la $LIBLTDL -export-dynamic],
+        [], [ignore], [ignore])
+
+LT_AT_NOINST_EXEC_CHECK([./main], [-dlopen m/module.la], [], [ignore], 
[ignore])
+
+AT_CHECK([$LIBTOOL --mode=install cp l/liba.la $libdir],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=install cp m/module.la $moddir],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=install cp main$EXEEXT $bindir],
+        [], [ignore], [ignore])
+rm -rf l m main$EXEEXT
+
+LTDL_LIBRARY_PATH=$moddir
+export LTDL_LIBRARY_PATH
+LT_AT_EXEC_CHECK([$bindir/main], [], [ignore], [ignore])
+
+AT_CLEANUP




reply via email to

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