[CXX-558] 'legacy' crashes on mongo::client::initialize() when using g++ and -std=c++11 Created: 14/Mar/15 Updated: 24/Mar/15 Resolved: 14/Mar/15 |
|
| Status: | Closed |
| Project: | C++ Driver |
| Component/s: | Implementation |
| Affects Version/s: | legacy-1.0.1 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Bartosz Zaborowski | Assignee: | Adam Midvidy |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
Simplest possible code: int main() { mongo::client::initialize(); return 0; }compilled with: causes segfault in mongo::client::initialize(). gdb says its somewhere in the ~Options(), but I don't understand what's going on. Without -std=c++11 everything works. The driver sources have been cloned out and built few days ago. |
| Comments |
| Comment by Andrey Sibiryov [ 24/Mar/15 ] |
|
I agree that that would probably be not the only issue around mixed mode builds, so yeah, makes sense. |
| Comment by Andrew Morrow (Inactive) [ 23/Mar/15 ] |
|
Hi kobolog - Part of the issue is that Boost itself does not guarantee that its own types are ABI stable between C++03 and C++11 builds. Given that we are dependent on Boost in our interface, we require that the application, the driver, and boost all be compiled in the same mode. In theory, we might be able to make it work, but given that this is the legacy driver, we have opted not to invest further effort in supporting mixed mode builds. |
| Comment by Andrey Sibiryov [ 23/Mar/15 ] |
|
So it's not "Works as Designed", to be honest =) |
| Comment by Andrey Sibiryov [ 23/Mar/15 ] |
|
I just encountered the same issue. In fact, it has nothing to do with C++ ABI changes. The reason for this crash is in src/mongo/stdx/functional.h: — For non-C++ 11 builds you typedef stdx::function<T> to be boost::function<T>. What happens is that in a driver built w/o C++ 11 support the _logAppender member of mongo::Options compiles to be a boost::function<T> type, while the code using that driver and compiled with C++ 11 support sees it as std::function<T> type. Since the destructor for mongo::Options is implicitly-defined, it's being generated when the actual project using the driver is being built, which in turn produces a code that uses std::function<T> destructor to destroy a boost::function<T> object, and that's when shit hits the fan. Implementing an explicit destructor for mongo::Options would solve this problem for everyone w/o any work on the user's side. |
| Comment by Bartosz Zaborowski [ 14/Mar/15 ] |
|
Great thanks for the answer, the first option seems ideal. I don't know why I didn't hit on it by myself |
| Comment by Adam Midvidy [ 14/Mar/15 ] |
|
So if you're checking before build time if the compiler supports Cxx11, you can literally try compiling a dummy file with --std=c++11 and seeing if it works. That's how we do it in SCons when building the legacy driver. see: https://github.com/mongodb/mongo-cxx-driver/blob/legacy/SConstruct#L1307 If you want to check what version of C++ you are building with at compile time, you can use the '_cplusplus' macro. See this page for details https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html As an aside, if you are already using C++ 11, you should take a look at our new C++ 11 driver, which can be found on the 'master' branch of the repository: https://github.com/mongodb/mongo-cxx-driver/tree/master. It presents a much nicer interface than the old driver, and includes a new BSON library as well. It's not yet production ready, but we would like people to experiment with it. Here is a blog post that gives an overview of it: https://www.mongodb.com/blog/post/introducing-new-c-driver. |
| Comment by Bartosz Zaborowski [ 14/Mar/15 ] |
|
Oh, right, I didn't add the --c++ 11=on switch. Now it works. Thanks for the help. But there is another question: how can I check (using autotools, CMake etc) whether a user building my software has a c++ 11 version or a c++98? I see a new mongo/config.h slightly differs form the old one, but relying on internals like "#define MONGO_HAVE_CXX11_ATOMICS 1" seems not to be a clean solution. |
| Comment by Adam Midvidy [ 14/Mar/15 ] |
|
Hi Bartosz, I am sorry to hear you are having trouble with the legacy driver. What flags did you compile the driver with? If you are building your application with C++ 11, you will need to compile the driver with C++ 11 as well. As it turns out, the ABI of the C++ 11 version of libstdc++ changed from the previous c++98 compatible version - you can read more about it here: https://gcc.gnu.org/wiki/Cxx11AbiCompatibility. Adam |