dlopen try / catch failure

dlopen try / catch failure

Post by Brian Hun » Wed, 02 Oct 2002 22:36:49



Hi everyone,

I cannot seem to catch errors either within or about objects opened with
dlopen. See the code below for an example.  I am using gcc 3.0.2 et al.,
as follows (this problem occurs with gcc 3.2, as well, I believe):





  Registered rae
Aborted (core dumped)

In the example below, I am autoregistering components into a factory map
(alpha) using the _init() symbol for on linkage execution.

x.h has the (abstract) interface class "doe", and the extern definition
for the factory "alpha".  x.cc allocates space for the factory, and has
a main function which iterates through the registered objects.  y.cc
extends "doe", into the class "rae", and defines extern "C" symbols
_init() which autoregisters the rae class and doe*Rae() which returns a
new rae object.

The simple explicit try / throw / catch block within the "rae::hello()"
function elucidates the issue I am having.  I have tried a number of
linking and compiling options, but have yet to find a combination that
solves this problem.

It is not even that there is failure passing a throw in a dlopen'ed
symbol up to the main, although that fails too; the try/catch block is
localized, yet still fails.

Any help would be greatly appreciated.

Cheers,
Brian

//---- x.h
#include <map>
#include <stdexcept>
#ifndef __DOE_
#define __DOE_
class doe {
     public:
     virtual string hello() = 0;

Quote:};

typedef doe* doe_t();
typedef map<string,doe_t*> fact;
extern fact alpha;

#endif
//----/ x.h

//---- x.cc
#include <iostream>
#include <string>
#include <dlfcn.h>

using namespace std;
#include "x.h"

extern "C"{
     fact alpha;

Quote:}

int main(int argc, char**argv) {
     void * handle = dlopen("./y.so", RTLD_GLOBAL|RTLD_NOW);
     if (handle == NULL) {
         cerr << "Error opening y.so: " << dlerror() <<endl;
         exit(-1);
     }

     map<string,doe_t*>::iterator sit = alpha.begin();
     for (; sit != alpha.end(); sit++) {
         doe * Y = alpha[sit->first]();
         std::cerr << " Registered " << sit->first << std::endl;
         std::cerr << " Hello: " << Y->hello() << std::endl;
     }

     dlclose(handle);

Quote:}

//----/ x.cc

//---- y.cc
#include <string>
#include <iostream>
#include <map>

using namespace std;
#include "x.h"

class rae : public doe {
     public:
     virtual string hello() {
         try {
                // remove this throw, and everything works.
             throw runtime_error("Why does this throw abort?");
             return "I am the lizard queen!";
         } catch (runtime_error &e) {
             cerr << " Caught exception: " << e.what() << endl;
             return "exception caught";
         }
     }

Quote:};

extern "C" {
     doe * Rae() { return new rae(); }
     void _init() { alpha["rae"] = Rae; }
Quote:}

//----/ y.cc
 
 
 

dlopen try / catch failure

Post by Neil Butterwort » Wed, 02 Oct 2002 22:45:51



> Hi everyone,

> I cannot seem to catch errors either within or about objects opened with
> dlopen. See the code below for an example.  I am using gcc 3.0.2 et al.,
> as follows (this problem occurs with gcc 3.2, as well, I believe):





>   Registered rae
> Aborted (core dumped)

> In the example below, I am autoregistering components into a factory map
> (alpha) using the _init() symbol for on linkage execution.

> x.h has the (abstract) interface class "doe", and the extern definition
> for the factory "alpha".  x.cc allocates space for the factory, and has
> a main function which iterates through the registered objects.  y.cc
> extends "doe", into the class "rae", and defines extern "C" symbols
> _init() which autoregisters the rae class and doe*Rae() which returns a
> new rae object.

> The simple explicit try / throw / catch block within the "rae::hello()"
> function elucidates the issue I am having.  I have tried a number of
> linking and compiling options, but have yet to find a combination that
> solves this problem.

> It is not even that there is failure passing a throw in a dlopen'ed
> symbol up to the main, although that fails too; the try/catch block is
> localized, yet still fails.

> Any help would be greatly appreciated.

dlopen() is not part of standard C++ and linkage errors/problems are
off-topic here. Ask this in one of the gnu newsgroups or (assuming you are
using Linux) in one in the comp.os.linux.programming hierarchy.

NeilB

 
 
 

dlopen try / catch failure

Post by Thomas Maier-Komo » Thu, 03 Oct 2002 21:29:32






>  Registered rae
> Aborted (core dumped)

This is the wrong way of creating the shared object.
The right way would be to use gcc directly:
$ g++ -g -Wall -fPIC -c y.cc
$ g++ -shared y.o -o y.so

I suggest using -fPIC so that the code will be position
independent - otherwise you might run into problems later.
When you try using g++ directly as I said above the linker
will fail for your code as you defined _init:

Quote:

> extern "C" {
>     doe * Rae() { return new rae(); }
>     void _init() { alpha["rae"] = Rae; }
> }
> //----/ y.cc

you shouldn't be doing this. When compiling C++ programs
let the compiler do the linking then you will have much
less problems. So comment out the _init line and then
compile and link as I suggested above and everything
will run fine. (I had the same problem some time ago...)

Cheers,

Tom
--
________________________________________________________________________
Dipl.-Ing. Thomas Maier-Komor                   http://www.rcs.ei.tum.de
Institute for Real-Time Computer Systems (RCS)      fon +49-89-289-23578
Technische Universitaet Muenchen, D-80290 Muenchen  fax +49-89-289-23555

 
 
 

dlopen try / catch failure

Post by Brian Hun » Fri, 04 Oct 2002 04:14:33


Thomas:

Thank you for the note; this was the problem -- evidently, linking with
ld is evil.

I used _init() because the global proxy class instances weren't having
their constructor called, another symptom of linking with ld.  g++
throws an error when _init() is defined (it duplicates the symbol in
libgcc), but linking with g++ does facilitate global classes whose
instances are constructed immediately with dlopen's RTLD_NOW, or
eventually with RTLD_LAZY.

Thanks for the note on -fPIC, too; all the anecdotal information is
greatly appreciated.

Cheers,

Brian






>>  Registered rae
>> Aborted (core dumped)

> This is the wrong way of creating the shared object.
> The right way would be to use gcc directly:
> $ g++ -g -Wall -fPIC -c y.cc
> $ g++ -shared y.o -o y.so

> I suggest using -fPIC so that the code will be position
> independent - otherwise you might run into problems later.
> When you try using g++ directly as I said above the linker
> will fail for your code as you defined _init:

>> extern "C" {
>>     doe * Rae() { return new rae(); }
>>     void _init() { alpha["rae"] = Rae; }
>> }
>> //----/ y.cc

> you shouldn't be doing this. When compiling C++ programs
> let the compiler do the linking then you will have much
> less problems. So comment out the _init line and then
> compile and link as I suggested above and everything
> will run fine. (I had the same problem some time ago...)

> Cheers,

> Tom

 
 
 

1. DLL call only works in try/catch block, but catch block is never called

I am calling a simple function in a DLL from another DLL, both of
which I have source for.  In debug mode this works fine.
In release mode, a crash seems to occur within the DLL call -
and it never returns.
If I enclose the DLL call in a try{}catch(...) {}block, the code
within the catch block is never called, and the DLL call executes
and returns ok.
I presume the try{} catch(...) block must be doing something to the
call stack which makes the call succeed?
Does anyone know why this works, and if there is another way of
making the call work which is less risky than ignoring all exceptions?

RH

2. printing thumbnails

3. try/catch does not catch SIGSEGV

4. VPN behind SMC router

5. try-catch: How is an exception w/ multiple catches processed?

6. Connect97 registration key

7. Will catch catch from previous catch?

8. WTB: MBX 1230XA 50/50/0k

9. Failure of type safety system to catch error -- why?

10. function-try-block failure?

11. How to use try -- catch block

12. tried to catch printscreen event

13. mutex_tryunlock() in try{}catch{} ?