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

2010-01-20 Thread Benjamin Bihler
Bob Friesenhahn wrote:

 While it has not been proven yet, I am suspecting that the failing C++
 exceptions have something to do with the way that libtool links these
modules.

 Does anyone have ideas about this?

We have just solved a similar problem: our binary was linked against a
shared library and when an exception was thrown in the shared library, a
segmentation fault occurred in the file libgcc_s.so. It was not possible to
catch the exception and continue the program.

Our system is Debian, we are working on 64 bit computers with g++ 4.3.2.
The problem mentioned above did not show on 32 bit (Open SuSE) systems.

The reason was: the shared library was linked against another static
library. Our automake mechanism told us, that this is not portable, but
everything seemed to work... exception catching exceptions.

Now we have changed our build mechanism. The shared library is not linked
against the static library anymore. Instead we include the static library
when we link our executable and suddenly everything works correctly. We can
throw exceptions and catch them and there are no segmentation faults
anymore.

You could try the following: create a very simple example consisting just
of a main file and a shared library (if you need one). Try to throw and
catch exceptions. Probably you will succeed. It does not matter whether you
use autoconf/libtool or not. Now increase the complexity until you arrive
at your read world situation. As soon as you detect that your exception is
not caught anymore you probably are very close to the solution! This way at
least worked in our case...

Ciao,
Benjamin




___
http://lists.gnu.org/mailman/listinfo/libtool


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

2010-01-20 Thread Benjamin Bihler
Bob Friesenhahn wrote:

 While it has not been proven yet, I am suspecting that the failing C++
 exceptions have something to do with the way that libtool links these
modules.

 Does anyone have ideas about this?

We have just solved a similar problem: our binary was linked against a
shared library and when an exception was thrown in the shared library, a
segmentation fault occurred in the file libgcc_s.so. It was not possible to
catch the exception and continue the program.

Our system is Debian, we are working on 64 bit computers with g++ 4.3.2.
The problem mentioned above did not show on 32 bit (Open SuSE) systems.

The reason was: the shared library was linked against another static
library. Our automake mechanism told us, that this is not portable, but
everything seemed to work... exception catching exceptions.

Now we have changed our build mechanism. The shared library is not linked
against the static library anymore. Instead we include the static library
when we link our executable and suddenly everything works correctly. We can
throw exceptions and catch them and there are no segmentation faults
anymore.

You could try the following: create a very simple example consisting just
of a main file and a shared library (if you need one). Try to throw and
catch exceptions. Probably you will succeed. It does not matter whether you
use autoconf/libtool or not. Now increase the complexity until you arrive
at your read world situation. As soon as you detect that your exception is
not caught anymore you probably are very close to the solution! This way at
least worked in our case...

Ciao,
Benjamin




___
http://lists.gnu.org/mailman/listinfo/libtool


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

2010-01-12 Thread Bob Friesenhahn

On Tue, 12 Jan 2010, Ralf Wildenhues wrote:

The test is currently skipped if the compiler doesn't like main.cpp
(which already exposes this API), so we should be safe there but not
test on as many systems as we could.  I added that for those kinds of
issues, but primarily for the older, pre-standard C++ compilers that
don't grok namespaces etc.

A missing throw() on virtual what() is a violation of ISO C++98 however.


I don't think that pre-standard C++ compilers are much of a concern.

Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/




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

2010-01-12 Thread Ralf Wildenhues
Hi Bob,

* Bob Friesenhahn wrote on Tue, Jan 12, 2010 at 05:26:27PM CET:
 On Tue, 12 Jan 2010, Ralf Wildenhues wrote:
 The test is currently skipped if the compiler doesn't like main.cpp
 (which already exposes this API), so we should be safe there but not
 test on as many systems as we could.  I added that for those kinds of
 issues, but primarily for the older, pre-standard C++ compilers that
 don't grok namespaces etc.
 
 A missing throw() on virtual what() is a violation of ISO C++98 however.
 
 I don't think that pre-standard C++ compilers are much of a concern.

I agree with you, in the sense that: let's not work hard to support
exception handling behavior of pre-standard C++ compilers.

OTOH, pre-standard C++ compilers are definitely a concern for testing.
I usually do pre-release testing on a couple of systems that have fairly
old and non-standard C++ compilers (no namespaces etc).  I don't want to
see errors stemming from this.

Thanks,
Ralf




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

2010-01-12 Thread Tim Rice
On Tue, 12 Jan 2010, Bob Friesenhahn wrote:

 On Tue, 12 Jan 2010, Ralf Wildenhues wrote:
  
  OTOH, pre-standard C++ compilers are definitely a concern for testing.
  I usually do pre-release testing on a couple of systems that have fairly
  old and non-standard C++ compilers (no namespaces etc).  I don't want to
  see errors stemming from this.
 
 I have not encountered such a limited C++ compiler for at least 12 years,
 including on archaic systems.

Just be aware that there are currently shipping systems based on
a product first released in 1992. I'm refering to OpenServer 5.0.7.
Its native C++ compiler uses an old ATT Cfront front end to the C compiler.

-- 
Tim RiceMultitalents(707) 887-1469
t...@multitalents.net






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

2010-01-11 Thread Ralf Wildenhues
Hi Bob,

* Bob Friesenhahn wrote on Mon, Jan 11, 2010 at 05:32:15AM CET:
 On Sun, 10 Jan 2010, Ralf Wildenhues wrote:
 
 My main comment is that it would be useful if the thrown class is
 derived from std:exception (or one of its standard derived classes)
 in order to flush out any issues which may stem from possible
 partial template instantiation in libstdc++ (or pre-compiled
 headers) as well as in the test translation unit.
 
 OK, sounds useful.  Would that entail more than just something like
 this incremental addition?
 
 I think that the virtual what() method needs to be provided or else
 you have only a partially implemented class:
[...]

Yup, indeed.  And we need to provide a throw()-qualified destructor as
well.

 But this is a better class to test with since it uses more standard
 library stuff and is therefore more likely to fail if something is
 wrong:
[...]

Thanks.  I'm pushing the test with this incremental addition squashed
into the first iteration of the patch, and listing you as second author.

Cheers,
Ralf

diff --git a/tests/exceptions.at b/tests/exceptions.at
index d551cb8..920b30e 100644
--- a/tests/exceptions.at
+++ b/tests/exceptions.at
@@ -29,7 +29,19 @@ AT_KEYWORDS([libltdl])
 CPPFLAGS=$LTDLINCL $CPPFLAGS
 
 AT_DATA([module.h],
-[[class modexc { };
+[[#include exception
+#include string
+class modexc : public std::exception {
+public:
+  modexc (std::string str) : message (str) { }
+  ~modexc () throw () { }
+  virtual const char *what () const throw ()
+  {
+return message.c_str ();
+  }
+private:
+  std::string message;
+};
 extern C int modfoo () throw (modexc);
 ]])
 
@@ -39,7 +51,7 @@ AT_DATA([module.cpp],
 
 int modbar (void) throw (modexc)
 {
-  throw modexc ();
+  throw modexc (exception in module);
 }
 
 extern C
@@ -48,16 +60,28 @@ int modfoo (void) throw (modexc)
   try {
 modbar ();
   }
-  catch (modexc) {
-std::cerr  caught inside module\n;
-throw modexc ();
+  catch (modexc e) {
+std::cerr  caught inside module:   e.what ()  '\n';
+throw modexc (exception from module);
   }
   return 0;
 }
 ]])
 
 AT_DATA([lib.h],
-[[class libexc { };
+[[#include exception
+#include string
+class libexc : public std::exception {
+public:
+  libexc (std::string str) : message (str) { }
+  ~libexc () throw () { }
+  virtual const char *what () const throw ()
+  {
+return message.c_str ();
+  }
+private:
+  std::string message;
+};
 int libfoo () throw (libexc);
 ]])
 
@@ -67,7 +91,7 @@ AT_DATA([lib.cpp],
 
 int libbar (void) throw (libexc)
 {
-  throw libexc ();
+  throw libexc (exception in library);
 }
 
 int libfoo (void) throw (libexc)
@@ -75,9 +99,9 @@ int libfoo (void) throw (libexc)
   try {
 libbar ();
   }
-  catch (libexc) {
-std::cerr  caught inside lib\n;
-throw libexc ();
+  catch (libexc e) {
+std::cerr  caught inside lib:   e.what ()  '\n';
+throw libexc (exception from library);
   }
   return 0;
 }
@@ -87,14 +111,26 @@ AT_DATA([main.cpp],
 [[#include ltdl.h
 #include cstdlib
 #include iostream
+#include exception
+#include string
 #include lib.h
 #include module.h
 
-class exc { };
+class exc : public std::exception {
+public:
+  exc (std::string str) : message (str) { }
+  ~exc () throw () { }
+  virtual const char *what () const throw ()
+  {
+return message.c_str ();
+  }
+private:
+  std::string message;
+};
 
 int foo (void) throw (exc)
 {
-  throw exc ();
+  throw exc (exception in program);
   return 0;
 }
 
@@ -104,8 +140,8 @@ int exceptions_in_prog (void)
   try {
 foo ();
   }
-  catch (exc) {
- std::cerr  caught\n;
+  catch (exc e) {
+ std::cerr  caught:   e.what ()  '\n';
 return 0;
   }
   return 1;
@@ -117,8 +153,8 @@ int exceptions_in_lib (void)
   try {
 libfoo ();
   }
-  catch (libexc) {
- std::cerr  caught\n;
+  catch (libexc e) {
+ std::cerr  caught:   e.what ()  '\n';
 return 0;
   }
   return 1;
@@ -161,7 +197,8 @@ int exceptions_in_module (void)
   try {
 (*pf) ();
   }
-  catch (modexc) {
+  catch (modexc e) {
+std::cerr  caught:   e.what ()  '\n';
 if (lt_dlclose (handle))
   {
 std::cerr  dlclose failed:   lt_dlerror ()  '\n';




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

2010-01-11 Thread Charles Wilson
Ralf Wildenhues wrote:
 Yup, indeed.  And we need to provide a throw()-qualified destructor as
 well.

A word of warning: not all implementations of std::exception use the
'throw' specifier on the virtual what() method. So, if you add it on
your derived class but the base class doesn't have it, you may get
[errors|warnings|pain].

Not sure what to do about it, short of adding a configure test...

--
Chuck





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

2010-01-11 Thread Ralf Wildenhues
Hi Charles,

* Charles Wilson wrote on Tue, Jan 12, 2010 at 12:42:21AM CET:
 Ralf Wildenhues wrote:
  Yup, indeed.  And we need to provide a throw()-qualified destructor as
  well.
 
 A word of warning: not all implementations of std::exception use the
 'throw' specifier on the virtual what() method. So, if you add it on
 your derived class but the base class doesn't have it, you may get
 [errors|warnings|pain].
 
 Not sure what to do about it, short of adding a configure test...

The test is currently skipped if the compiler doesn't like main.cpp
(which already exposes this API), so we should be safe there but not
test on as many systems as we could.  I added that for those kinds of
issues, but primarily for the older, pre-standard C++ compilers that
don't grok namespaces etc.

A missing throw() on virtual what() is a violation of ISO C++98 however.

Cheers,
Ralf





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

2010-01-10 Thread Ralf Wildenhues
Hi Bob,

* Bob Friesenhahn wrote on Sat, Jan 09, 2010 at 08:03:11PM CET:
 On Sat, 9 Jan 2010, Ralf Wildenhues wrote:
 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.
 
 My main comment is that it would be useful if the thrown class is
 derived from std:exception (or one of its standard derived classes)
 in order to flush out any issues which may stem from possible
 partial template instantiation in libstdc++ (or pre-compiled
 headers) as well as in the test translation unit.

OK, sounds useful.  Would that entail more than just something like
this incremental addition?


diff --git a/tests/exceptions.at b/tests/exceptions.at
index d551cb8..77a94c1 100644
--- a/tests/exceptions.at
+++ b/tests/exceptions.at
@@ -29,7 +29,8 @@ AT_KEYWORDS([libltdl])
 CPPFLAGS=$LTDLINCL $CPPFLAGS
 
 AT_DATA([module.h],
-[[class modexc { };
+[[#include exception
+class modexc : public std::exception { };
 extern C int modfoo () throw (modexc);
 ]])
 
@@ -57,7 +58,8 @@ int modfoo (void) throw (modexc)
 ]])
 
 AT_DATA([lib.h],
-[[class libexc { };
+[[#include exception
+class libexc : public std::exception { };
 int libfoo () throw (libexc);
 ]])
 
@@ -87,10 +89,11 @@ AT_DATA([main.cpp],
 [[#include ltdl.h
 #include cstdlib
 #include iostream
+#include exception
 #include lib.h
 #include module.h
 
-class exc { };
+class exc : public std::exception { };
 
 int foo (void) throw (exc)
 {





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

2010-01-10 Thread Bob Friesenhahn

On Sun, 10 Jan 2010, Ralf Wildenhues wrote:


My main comment is that it would be useful if the thrown class is
derived from std:exception (or one of its standard derived classes)
in order to flush out any issues which may stem from possible
partial template instantiation in libstdc++ (or pre-compiled
headers) as well as in the test translation unit.


OK, sounds useful.  Would that entail more than just something like
this incremental addition?


I think that the virtual what() method needs to be provided or else 
you have only a partially implemented class:


class MyException : public std::exception
{
  public;
MyException() {}

  virtual const char *what() const throw()
  {
 return My message;
  }
};

But this is a better class to test with since it uses more standard 
library stuff and is therefore more likely to fail if something is 
wrong:


#include exception
#include string
class MyException : public std::exception
{
  public;
MyException(std::string str)
 : message(str)
{
}

  virtual const char *what() const throw()
  {
 return message.c_str();
  }

  private:
std::string message;
};

Which can be thrown with

  throw MyException(My message);

Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/




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

2010-01-09 Thread Ralf Wildenhues
[ 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 000..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 ())
+  {
+ 

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

2010-01-09 Thread Ralf Wildenhues
* 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.

 Over the years I have encountered a number of cases where C++
 exceptions don't work,

Do you use dlopened modules?  If yes, try adding -export-dynamic to the
link flags of the program, and try enabling global symbol resolution for
opened modules.

I'll post a testsuite addition on libtool-patches to try out.

Do you mix C++ code with other code, e.g., code compiled with the C
compiler?  Some non-GCC compilers may need other switches for exception
handling to work right, e.g., +eh for the HP-UX compiler.

Cheers,
Ralf


___
http://lists.gnu.org/mailman/listinfo/libtool


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

2010-01-09 Thread Bob Friesenhahn

On Sat, 9 Jan 2010, Ralf Wildenhues wrote:


* 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.



Over the years I have encountered a number of cases where C++
exceptions don't work,


Do you use dlopened modules?  If yes, try adding -export-dynamic to the
link flags of the program, and try enabling global symbol resolution for
opened modules.


There is the option to use dlopened modules, but the problem also 
occurs in a static build.



Do you mix C++ code with other code, e.g., code compiled with the C
compiler?  Some non-GCC compilers may need other switches for exception
handling to work right, e.g., +eh for the HP-UX compiler.


There is of course C code in the equation.  I don't know how to avoid 
that. C++ exceptions are not being thrown across/through C code. 
Exceptions are working fine with the HP-UX compiler.


The only compilers where I have seen C++ exception problems are ones 
which are either GCC or using GCC's front-end (like llvm-gcc).


The issue may or may not be related to libtool.

Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/


___
http://lists.gnu.org/mailman/listinfo/libtool


libtool, llvm-gcc, failing C++ exceptions

2010-01-05 Thread Bob Friesenhahn
Using 'llvm-gcc' (GCC frontend to llvm compiler) I find that C++ 
exceptions do not work (are not caught) in the built programs.


When building C++ programs and libraries, libtool tells the compiler 
to not supply its own runtime or libraries, and then specifies what it 
believes are the correct runtime and libraries.


Over the years I have encountered a number of cases where C++ 
exceptions don't work, and llvm-gcc (as provided with FreeBSD) is an 
example.  Another case is with 64-bit code on AMD64 Solaris 10 where 
C++ exceptions don't work in GCC-built code (but they do work with the 
Sun compiler).  An identical problem was reported in 64-bit AMD64 code 
under FreeBSD 7.2.  Unfortunately, this is a complex problem because 
sometimes the C++ exceptions stop working after a large body of code 
(e.g. GraphicsMagick + libtiff + ) has been linked into it.  It 
has something to do with process initialization.


While it has not been proven yet, I am suspecting that the failing C++ 
exceptions have something to do with the way that libtool links these 
modules.


Does anyone have ideas about this?

Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/


___
http://lists.gnu.org/mailman/listinfo/libtool


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

2010-01-05 Thread dherring
Bob Friesenhahn wrote:
 While it has not been proven yet, I am suspecting that the failing C++
 exceptions have something to do with the way that libtool links these
 modules.

 Does anyone have ideas about this?

Do all exceptions fail, or just some exceptions?

For example, does something like the following work?

bool handled=false;
try { throw 100; /* or a type local to this compilation unit */ }
catch(int x) { handled=true; }
catch(...)
{
  handled=true;
  assert(false); // should be handled earlier
}
assert(handled);

Many systems catch exceptions based on the address of a symbol that gets
generated with the class destructor; that's caused all my problems when
passing exceptions between libraries.

- Daniel



___
http://lists.gnu.org/mailman/listinfo/libtool


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

2010-01-05 Thread Bob Friesenhahn

On Tue, 5 Jan 2010, dherr...@tentpost.com wrote:


Bob Friesenhahn wrote:

While it has not been proven yet, I am suspecting that the failing C++
exceptions have something to do with the way that libtool links these
modules.

Does anyone have ideas about this?


Do all exceptions fail, or just some exceptions?

For example, does something like the following work?


It can not even throw and catch an 'int' in the same scope.  I see the 
same problem (two years now) for an AMD64 build under Solaris 10, but 
not for an AMD64 build under Linux. The test program I am using is 
attached.


Under Solaris 10, the runtime is nice enough to print this:

  terminate called after throwing an instance of 'int'
  Segmentation Fault - core dumped

whereas with llvm-gcc under FreeBSD 8.0 I just get:

  Segmentation fault (core dumped)

I have never seen any such problem under SPARC Solaris 10.

The test-suite included in my package tests the ability to throw and 
catch its own exceptions, which are derived in a heirarchical fashion 
(inheritance) from std::exception.  As further clarification, this 
problem occurs in a static build where the C++ standard library and 
some other linked-in libraries are shared, but all of my application 
code (including the throw/catch path being tested) is built as static.


In the early days of libtool, the options that GCC would use while 
linking were teased out of GCC, but then the system linker was used to 
do the linking.  This seemed to cause some problems so now the C++ 
compiler is used for linking, but libtool tells GCC not to apply any 
of its normal runtime or libraries, and then libtool passes all of 
this stuff at link-time.  If the compiler is not GCC, then libtool 
still usually uses the C++ compiler, but it simply tells the C++ 
compiler to do the link, without trying to intuit what it would do 
(and the result works).


As we have learned, GCC is proven to sometimes lie about the options 
it would apply given a particular set of options so it seems possible 
that libtool sometimes applies the wrong options while linking.


This is what happens when a small C++ test program is compiled and 
linked using llvm-c++:


depbase=`echo Magick++/tests/exceptions.o | sed 
's|[^/]*$|.deps/|;s|\.o$||'`;\
llvm-c++ -DHAVE_CONFIG_H -I. 
-I/home/bfriesen/src/graphics/GraphicsMagick-head -I./magick  -I. 
-I/home/bfriesen/src/graphics/GraphicsMagick-head 
-DLT_CONFIG_H='magick/magick_config.h' -DLTDL -I. 
-I/home/bfriesen/src/graphics/GraphicsMagick-head -Iltdl 
-I/home/bfriesen/src/graphics/GraphicsMagick-head/ltdl 
-I/home/bfriesen/src/graphics/GraphicsMagick-head/ltdl/libltdl 
-I/home/bfriesen/src/graphics/GraphicsMagick-head/Magick++/lib 
-I/usr/local/include/freetype2 -I/usr/local/include 
-I/usr/local/include -I/usr/local/include/libxml2  -g -O -march=native 
-D_THREAD_SAFE -pthread -MT Magick++/tests/exceptions.o -MD -MP -MF 
$depbase.Tpo -c -o Magick++/tests/exceptions.o 
/home/bfriesen/src/graphics/GraphicsMagick-head/Magick++/tests/exceptions.cpp 
\

mv -f $depbase.Tpo $depbase.Po
/bin/sh ./libtool  --tag=CXX 
--mode=link llvm-c++  -g -O 
-march=native -D_THREAD_SAFE -pthread -no-undefined -L/usr/local/lib 
-L/usr/local/lib -R/usr/local/lib -L/usr/local/lib -L/usr/local/lib -o 
Magick++/tests/exceptions Magick++/tests/exceptions.o 
Magick++/lib/libGraphicsMagick++.la
libtool: link: llvm-c++ -g -O -march=native -D_THREAD_SAFE -pthread -o 
Magick++/tests/exceptions Magick++/tests/exceptions.o 
-L/usr/local/lib Magick++/lib/.libs/libGraphicsMagick++.a 
-L/usr/ports/lang/llvm-gcc4/work/llvm-gcc4.2-2.5.source/obj/i386-portbld-freebsd7.0/libstdc++-v3/src 
-L/usr/ports/lang/llvm-gcc4/work/llvm-gcc4.2-2.5.source/obj/i386-portbld-freebsd7.0/libstdc++-v3/src/.libs 
-L/usr/ports/lang/llvm-gcc4/work/llvm-gcc4.2-2.5.source/obj/./gcc 
/scratch/bfriesen/build/GraphicsMagick-16-static-llvm/magick/.libs/libGraphicsMagick.a 
-llcms /usr/local/lib/libtiff.so -ljbig /usr/local/lib/libfreetype.so 
/usr/local/lib/libjasper.so /usr/local/lib/libjpeg.so -lpng 
/usr/local/lib/libwmflite.so /usr/local/lib/libXext.so 
/usr/local/lib/libSM.so /usr/local/lib/libICE.so 
/usr/local/lib/libX11.so /usr/local/lib/libxcb.so 
/usr/local/lib/libXau.so /usr/local/lib/libXdmcp.so 
/usr/local/lib/libpthread-stubs.so -lrpcsvc -lbz2 
/usr/local/lib/libxml2.so /usr/local/lib/libiconv.so -lz -lpthread 
/usr/local/lib/llvm-gcc-2.5/libstdc++.so -lm -lgcc_s 
/usr/local/lib/llvm-gcc-2.5/libgomp.so -pthread -Wl,-rpath 
-Wl,/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib/llvm-gcc-2.5 
-Wl,-rpath -Wl,/usr/local/lib -Wl,-rpath 
-Wl,/usr/local/lib/llvm-gcc-2.5


Bob
--
Bob Friesenhahn
bfrie...@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,http://www.GraphicsMagick.org/// This may look like C code, but it is really -*- C++ -*-
//
// Copyright Bob Friesenhahn, 1999-2010
//
// Tests for throwing exceptions
//

#include Magick++.h
#include string
#include iostream

using 

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

2010-01-05 Thread Ralf Wildenhues
Hi Bob,

* 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.
 
 When building C++ programs and libraries, libtool tells the compiler
 to not supply its own runtime or libraries, and then specifies what
 it believes are the correct runtime and libraries.
 
 Over the years I have encountered a number of cases where C++
 exceptions don't work, and llvm-gcc (as provided with FreeBSD) is an
 example.  Another case is with 64-bit code on AMD64 Solaris 10 where
 C++ exceptions don't work in GCC-built code (but they do work with
 the Sun compiler).  An identical problem was reported in 64-bit
 AMD64 code under FreeBSD 7.2.  Unfortunately, this is a complex
 problem because sometimes the C++ exceptions stop working after a
 large body of code (e.g. GraphicsMagick + libtiff + ) has been
 linked into it.  It has something to do with process initialization.
 
 While it has not been proven yet, I am suspecting that the failing
 C++ exceptions have something to do with the way that libtool links
 these modules.
 
 Does anyone have ideas about this?

Try to find out if exceptions work when you manually override what
libtool does.  My first guess would be that only library linking is
wrong, but not program linking.  In an up to date build tree of GM:
  rm magick/libGraphicsMagick.la
  env RM=echo make magick/libGraphicsMagick.la

then copy and paste the link command line, adjust it the way you think
it should have looked instead, and run it.  Let's hope the $RM override
keeps all required intemediate files for you.

Then rebuild a program that uses this library.  Does exception handling
work now?  You may have to rinse and repeat with other suspected-broken
libraries.

Hope that helps.

Cheers,
Ralf


___
http://lists.gnu.org/mailman/listinfo/libtool