[C++-sig] EXTERNAL: Re: Odd dlopen behavior

Niall Douglas s_sourceforge at nedprod.com
Thu Feb 2 13:03:46 CET 2012


On 2 Feb 2012 at 6:00, Davidson, Josh wrote:

> Neil, great information, but I did track this problem down to a quirk with Py++.
> [snip]
> After finding references to this problem as far back as 2006, I decided
> to switch over to balanced_split_module.  This has its own set of
> problems.  The first is that it is highly prone to divide by zero
> errors.  One quick way to reproduce this issue is to wrap one class and
> specify a split count of 2.  Obviously not a wise combo, but it's an
> easy error case that Py++ should handle. 

It's been a long time since I used Py++, or indeed BPL. Neither has 
seen much work done on them in recent years, so I should imagine both 
will have suffered from a certain amount of bitrot.

> So anyways, the root of *this* problem is how balanced_split_module
> creates its registration functions.  For each extension, it creates one
> register function for each file it writes in the form:  void
> register_classes_<N>()    Obviously, these collide when you create more
> than one extension using balanced_split_module and enable RTLD_GLOBAL. 

In my own code, registration functions are always static and pass 
their own address into the runtime. The runtime does a two-pass 
initialisation, so first off it eliminates any duplicate registration 
functions whose address lies within the same DLL. Then and only then 
does it start complaining.

That solution allows you to throw registration functions anywhere and 
let the runtime sort out what's what. It also lets you operate 
per-DLL and DLL-specialised registries, something I suggested to Jim 
Bosch for the next release of BPL a few months back. Knowing which 
DLL registered what is also very useful for debugging.

> One quick solution to this problem would be to prepend the extension
> name to the name of the registration functions, e.g.:
> <module>_register_classes_<N>  Since the module name is used to name the
> files, its easily accessible and would solve a lot of problems.  Of
> course, if you have modules with the same name in different packages you
> would run into this again. 

This is a bad solution. Firstly, who is to say that type Foo in 
extension X is or is not the same as type Foo in extension Y even if 
both have the same type, same length, same traits and live in the 
same namespace? Yes I know it's a violation of ODR, but in the real 
world maybe they are the same, and maybe they aren't - people use 
DLLs to violate ODR all the time, it's one of their big utilities. 
You need a way of explicitly specifying if the types are equal or 
aren't. Type registration functions aren't the place to do it, 
however in my own code I have a concept of "type conversion" 
registration functions which are used to declare runtime type 
conversions which kick in if the static (metaprogrammed) type 
conversions fail. When you say type Foo is the same between 
registries X and Y it simply bumps that type out of X and Y and into 
the common parent registry between X and Y, so searches fail in X and 
Y and jump into the parent where they get resolved as being 
identical.

Now me and Dave Abrahams come to a disagreement after this - he does 
not feel that there ought to be separate static and runtime type 
registries. And I can see his point. But we disagree :). I'm very 
fond of binding together other people's libraries in order to 
personally avoid writing as much code as possible, so I think in 
terms of ways of getting other people's code to cooperate, and for 
that I like to override when needs be which is blatent ODR breaking. 
Dave has a different approach, and therefore a different philosophy.

(And before Dave points out that that wasn't my philosophy in the 
past, and indeed he once argued with me strenuously to use Boost 
rather than write my own metaprogramming library, I admit I was wrong 
and he was right)

However, back to the point. It would appear you're running into well 
known limitations in BPL. Some years ago, people's needs were 
generally simpler and BPL worked without issue for them. As years 
move on, more and more complex use cases are becoming common.

Bitrot. It consumes all code eventually.

Niall

-- 
Technology & Consulting Services - ned Productions Limited.
http://www.nedproductions.biz/. VAT reg: IE 9708311Q. Company no: 
472909.





More information about the Cplusplus-sig mailing list