Folks:
We're trying to get pycryptopp to link against the system-provided
libcryptopp.so on Debian and Fedora, as well as to not crash in
mysterious ways some of the time. Here is the most recent note that
I sent about this issue to the cryptopp-users mailing list:
http://groups.google.com/group/cryptopp-users/browse_thread/thread/
eb815f228db50380
Regards,
Zooko
Begin forwarded message:
From: Zooko Wilcox-O'Hearn <[email protected]>
Date: May 23, 2009 21:03:29 PM MDT
To: Zooko Wilcox-O'Hearn <[email protected]>
Cc: Wei Dai <[email protected]>, "Crypto++ Users" <cryptopp-
[email protected]>
Subject: Re: that problem with comparing types across DLLs
Dear Wei Dai et al.:
It is as I feared -- using the RTLD_GLOBAL flag for dlopen solves
the problem in question but leads to other problems.
My project produces four different .so files, each of which is
built by including some of the .o files from Crypto++. If I set
RTLD_GLOBAL then if more than one of these .so files is loaded into
the same process, the second and later ones to be loaded have
something messed up which quickly leads to a crash. Attached is
the output of valgrind showing the details of one such crash.
(This is all 100% reproducible using the pycryptopp unit test suite.)
What I really want is for there to exist some way in C++ that you
can express the following alternatives:
1. For a given symbol, for example the type_info of an exception
class, then any code which #included that symbol, when loaded at
run-time, will get the same unique value so that throw and catch
and name-based arguments will work between any pair of DSOs.
2. For other symbols, any code which #includes that code will get
its own separate address (symbol value) at run-time so that changes
made to the value stored in that address (symbol) by one DSO won't
affect other DSOs.
I *think* that this is the intent of __declspec(dllexport) and its
brethren.
However, not understanding how to make this work with g++, if it is
even possible, or if it is even a coherent thing to want, my next
step is to declare that you can't have more than one DSO which uses
Crypto++ code in your process, so I'll refactor my pycryptopp
library to build all of the four features (AES, SHA256, RSA, and
ECDSA), as well as upcoming features (XSalsa20, Tiger) in one DSO
which is linked by including .o files from Crypto++. This will
work as long as nobody tries to use my DSO along with another DSO
which also uses Crypto++.
Oh, there's another alternative open to me -- make the pycryptopp
build system build a custom Crypto++ DSO (or maybe just the
standard Crypto++ DSO as specified by the Crypto++ GNUmakefile),
and then build four DSOs each of which dynamically links to that
shared DSO and continue to use RTLD_GLOBAL. This is actually
already shown to work for our current unit test suite, but I don't
trust it because I don't understand why RTLD_GLOBAL causes these
crashes in other situations.
Regards,
Zooko
test (pycryptopp.test.test_ecdsa.SignAndVerify) ... ==26182== Jump to the
invalid address stated on the next line
==26182== at 0x0: ???
==26182== by 0x9D1B722: CryptoPP::AsymmetricMultiply(unsigned long long*,
unsigned long long*, unsigned long long const*, unsigned long, unsigned long
long const*, unsigned long) (integer.cpp:2199)
==26182== by 0x9D1C5C1: CryptoPP::Divide(unsigned long long*, unsigned long
long*, unsigned long long*, unsigned long long const*, unsigned long, unsigned
long long const*, unsigned long) (integer.cpp:2538)
==26182== by 0x9D1D8EB: CryptoPP::PositiveDivide(CryptoPP::Integer&,
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&)
(integer.cpp:3741)
==26182== by 0x9D1D932: CryptoPP::Integer::Divide(CryptoPP::Integer&,
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&)
(integer.cpp:3746)
==26182== by 0x9D1DA00: CryptoPP::Integer::Modulo(CryptoPP::Integer const&)
const (integer.cpp:3800)
==26182== by 0x9C58C30:
CryptoPP::MontgomeryRepresentation::ConvertIn(CryptoPP::Integer const&) const
(modarith.h:132)
==26182== by 0xA574DC6: CryptoPP::ECP::ECP(CryptoPP::ECP const&, bool)
(ecp.cpp:32)
==26182== by 0xA51A6D2:
CryptoPP::EcPrecomputation<CryptoPP::ECP>::SetCurve(CryptoPP::ECP const&)
(ecp.h:115)
==26182== by 0xA51FA75:
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::Initialize(CryptoPP::OID
const&) (eccrypto.cpp:433)
==26182== by 0xA520799:
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::DL_GroupParameters_EC(CryptoPP::OID
const&) (eccrypto.h:37)
==26182== by 0xA620706: ??? (ecdsamodule.cpp:289)
==26182== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==26182==
==26182== Process terminating with default action of signal 11 (SIGSEGV)
==26182== Bad permissions for mapped region at address 0x0
==26182== at 0x0: ???
==26182== by 0x9D1B722: CryptoPP::AsymmetricMultiply(unsigned long long*,
unsigned long long*, unsigned long long const*, unsigned long, unsigned long
long const*, unsigned long) (integer.cpp:2199)
==26182== by 0x9D1C5C1: CryptoPP::Divide(unsigned long long*, unsigned long
long*, unsigned long long*, unsigned long long const*, unsigned long, unsigned
long long const*, unsigned long) (integer.cpp:2538)
==26182== by 0x9D1D8EB: CryptoPP::PositiveDivide(CryptoPP::Integer&,
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&)
(integer.cpp:3741)
==26182== by 0x9D1D932: CryptoPP::Integer::Divide(CryptoPP::Integer&,
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&)
(integer.cpp:3746)
==26182== by 0x9D1DA00: CryptoPP::Integer::Modulo(CryptoPP::Integer const&)
const (integer.cpp:3800)
==26182== by 0x9C58C30:
CryptoPP::MontgomeryRepresentation::ConvertIn(CryptoPP::Integer const&) const
(modarith.h:132)
==26182== by 0xA574DC6: CryptoPP::ECP::ECP(CryptoPP::ECP const&, bool)
(ecp.cpp:32)
==26182== by 0xA51A6D2:
CryptoPP::EcPrecomputation<CryptoPP::ECP>::SetCurve(CryptoPP::ECP const&)
(ecp.h:115)
==26182== by 0xA51FA75:
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::Initialize(CryptoPP::OID
const&) (eccrypto.cpp:433)
==26182== by 0xA520799:
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::DL_GroupParameters_EC(CryptoPP::OID
const&) (eccrypto.h:37)
==26182== by 0xA620706: ??? (ecdsamodule.cpp:289)
==26182==
==26182== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 9656 from 9)
==26182== malloc/free: in use at exit: 16,310,629 bytes in 26,717 blocks.
==26182== malloc/free: 88,524 allocs, 61,807 frees, 171,746,080 bytes allocated.
==26182== For counts of detected errors, rerun with: -v
==26182== searching for pointers to 26,717 not-freed blocks.
==26182== checked 15,993,824 bytes.
==26182==
==26182== LEAK SUMMARY:
==26182== definitely lost: 28 bytes in 1 blocks.
==26182== possibly lost: 224,148 bytes in 456 blocks.
==26182== still reachable: 16,086,453 bytes in 26,260 blocks.
==26182== suppressed: 0 bytes in 0 blocks.
==26182== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault
_______________________________________________
tahoe-dev mailing list
[email protected]
http://allmydata.org/cgi-bin/mailman/listinfo/tahoe-dev