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 namespace std;

using namespace Magick;

int main( int /*argc*/, char ** argv)
{
  // Initialize GraphicsMagick
  InitializeMagick(*argv);
      
  int failures=0;

  cout << "Checking for working exceptions (may crash and burn) ..." << endl;
  cout.flush();

  {      
    // Basic exception test
    try
      {
        failures++;
        cout << "Throwing native 'int' exception" << endl;
        cout.flush();
        throw int(100);
      }
    catch ( int /*value_*/ )
      {
        cout << "Successfully caught native 'int' exception" << endl;
        cout.flush();
        failures--;
      }

    // Throw a Magick++ exception class.
    try
      {
        failures++;
        cout << "Throwing 'Magick::WarningResourceLimit' exception" << endl;
        cout.flush();
        throw WarningResourceLimit("How now brown cow?");
      }
    catch( Exception & /*error_*/ )
      {
        cout << "Successfully caught 'Magick::WarningResourceLimit' exception" 
<< endl;
        cout.flush();
        failures--;
      }
      
    // A more complex test
    try
      {
        unsigned int columns = 640;
        unsigned int rows = 480;
        Geometry geometry(columns,rows);
        Color canvasColor( "red" );
        Image image( geometry, canvasColor);
        {
          try
            {
              failures++;
              cout << "Throwing library 'Magick::Exception' exception" << endl;
              cout.flush();
              image.directory();
            }
          catch ( Exception& /*error_*/ )
            {
              cout << "Successfully caught library 'Magick::Exception' 
exception" << endl;
              cout.flush();
              failures--;
            }
        }
          
      }
    catch( Exception &error_ )
      {
        cout << "Bogus catch: Caught exception: " << error_.what() << endl;
        cout.flush();
        return 1;
      }
    catch( exception &error_ )
      {
        cout << "Bogus catch: Caught exception: " << error_.what() << endl;
        cout.flush();
        return 1;
      }
  
    if ( failures )
      {
        cout << failures << " failures" << endl;
        cout.flush();
        return 1;
      }
    cout << "Exception testing passed!" << endl;
  }

  return 0;
}
_______________________________________________
http://lists.gnu.org/mailman/listinfo/libtool

Reply via email to