[C++-sig] that problem with comparing types across DLLs

Zooko O'Whielacronx zookog at gmail.com
Wed May 27 21:52:54 CEST 2009


On Wed, May 27, 2009 at 12:20 PM, Niall Douglas
<s_sourceforge at nedprod.com> wrote:
>
> If it turns out that GCC is incapable of emitting the correct symbol
> visibility declarations for a particular library, then an issue
> should be filed with GCC's bugtracker. They have been most responsive
> in the past with corner cases so I don't see it as an issue.

Thanks for the encouragement on that front.  I'll keep in mind that
gcc developers are responsive about these issues.  That helps.

> I am afraid I simply don't get this. Crypto++ seems to have a build
> option for Windows as a DLL. If it does then it ports very easily
> indeed to GCC symbol visibility. The only possible problem could be
> if he used a lot of dllexported non-class based static variables
> which you shouldn't in object orientatation.

As Wei Dai explained in this thread:

http://groups.google.com/group/cryptopp-users/browse_thread/thread/eb815f228db50380

He implemented the "CRYPTOPP_DLL" build of Crypto++ only because it
was a requirement for FIPS validation, and it doesn't include a lot of
the functionality of the library -- only that subset of the
functionality which was being validated.  Also, he attempted to port
the same shared-lib build to Unix and failed and gave up.

I don't know whether Crypto++ dllexports a lot of non-class-based
static variables.  It is a very big library with a big API and I don't
have a good understanding of its scope.

> If I'm reading between the lines here correctly, are you saying that
> your libcrypto++ uses vX.XX of a libaes library but you want that to
> interoperate which any other shared library which uses vY.YY of the
> same libaes library? Obviously should APIs move out of step you get
> all sorts of pernicious bugs.

Wei Dai is the author of Crypto++, and I'm the author of pycryptopp.
Pycryptopp is merely a few Python wrappers for certain Crypto++
features, plus a few small utilities that I need.  The current build
system of pycryptopp generates a module named aes.so, one named
ecdsa.so, one named rsa.so and one named sha256.so.  Each of these
requires different functionality from Crypto++.  The current build
system links aes.so with the Crypto++ object files which are built
from the Crypto++ .cpp files.  This works, but it is not allowed to
deploy as an official Debian or Fedora package when built like this.

If I instead link aes.so with "-lcryptopp" and use the Debian- or
Fedora- provided libcryptopp.so at load-time (using the default Python
behavior of RTLD_LOCAL), it fails, because RTTI symbols are not merged
at load-time, so an exception of type InvalidKeyLength, thrown from
libcryptopp.so will not be caught by the handler in aes.so which
attempts to catch exceptions of that type, because the RTTI symbol for
InvalidKeyLength in libcryptopp.so has a different value than the RTTI
symbol for InvalidKeyLength in aes.so.

If I then set the RTLD_GLOBAL flag, then loading aes.so (which
dynamically depends on libcryptopp.so) works, and the exception
handler can catch exceptions of the specific type.  But, if I then
load both aes.so and rsa.so into the same Python interpreter, it seg
faults.  Here is the valgrind stack trace of that event:

http://groups.google.com/group/cryptopp-users/attach/1a5553410c6976e5/crash.txt?part=2

So I am now engaged in refactoring pycryptopp so that instead of
separate aes.so and rsa.so (and so on), there is instead a single
_pycryptopp.so which provides all of the functionality, and then there
is an aes.py and an rsa.py which import the appropriate names from
_pycryptopp and leave out the other names.

The problem with this strategy, I think, is that if someone were to
load _pycryptopp.so using RTLD_GLOBAL, and then someone else were to
load libcryptopp.so into the same Python interpreter, it would seg
fault.  But maybe nobody will ever want to do that.

Thanks for you help!

Regards,

Zooko


More information about the Cplusplus-sig mailing list