[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gcc-bugs
Subject:    [Bug lto/43581] exception handling broken across shared libaries with -fuse-linker-plugin
From:       "rwild at gcc dot gnu dot org" <gcc-bugzilla () gcc ! gnu ! org>
Date:       2010-03-31 18:49:50
Message-ID: 20100331184950.16996.qmail () sourceware ! org
[Download RAW message or body]



------- Comment #6 from rwild at gcc dot gnu dot org  2010-03-31 18:49 -------
Here's the analogous test case from Libtool for dlopen'ed modules.  Also passes
when -fuse-linker-plugin is removed from the link line for module.so.

CXX=g++
CXXFLAGS='-O2 -flto'
LDFLAGS='-fuse-linker-plugin'

cat >module.h <<\EOF
#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);
EOF

cat >module.cpp <<\EOF
#include <iostream>
#include "module.h"

int modbar (void) throw (modexc)
{
  throw modexc ("exception in module");
}

extern "C"
int modfoo (void) throw (modexc)
{
  try {
    modbar ();
  }
  catch (modexc e) {
    std::cerr << "caught inside module: " << e.what () << '\n';
    throw modexc ("exception from module");
  }
  return 0;
}
EOF

cat >main.cpp <<\EOF
#include <dlfcn.h>
#include <iostream>
#include <exception>
#include <string>
#include "module.h"

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 exceptions_in_module (void)
{
  std::cerr << "exceptions_in_module\n";

  void *handle = dlopen ("module.so", RTLD_GLOBAL | RTLD_LAZY);
  if (handle == NULL)
    {
      std::cerr << "dlopen failed: " << dlerror () << '\n';
      return 1;
    }

  typedef int (*pfun) (void);
  pfun pf = (pfun) dlsym (handle, "modfoo");
  if (pf == NULL)
    {
      std::cerr << "dlsym failed: " << dlerror () << '\n';
      return 1;
    }

  try {
    (*pf) ();
  }
  catch (modexc e) {
    std::cerr << "caught: " << e.what () << '\n';
    if (dlclose (handle))
      {
        std::cerr << "dlclose failed: " << dlerror () << '\n';
        return 1;
      }
    return 0;
  }
  return 1;
}

int main (void)
{
  if (exceptions_in_module ())
    return 1;
  return 0;
}
EOF

$CXX $CXXFLAGS -c main.cpp
$CXX $CXXFLAGS -c module.cpp -fPIC -o module.o
$CXX $CXXFLAGS $LDFLAGS -fPIC -shared module.o -o module.so
$CXX $CXXFLAGS $LDFLAGS -o main main.o -Wl,--export-dynamic -ldl
LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ./main


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43581

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic