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 --- Tahoe, the Least-Authority Filesystem -- http://allmydata.org store your data: $10/month -- http://allmydata.com/?tracking=zsig I am available for work -- http://zooko.com/résumé.html --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the "Crypto++ Users" Google Group. To unsubscribe, send an email to [email protected]. More information about Crypto++ and this group is available at http://www.cryptopp.com. -~----------~----~----~----~------~----~------~--~---
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
