[SERVER-1266] libmongoclient should not link with xulrunner's libmozjs, causes subtle memory errors Created: 21/Jun/10 Updated: 12/Jul/16 Resolved: 26/Jul/10 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Internal Client |
| Affects Version/s: | 1.5.3 |
| Fix Version/s: | 1.5.7 |
| Type: | Improvement | Priority: | Major - P3 |
| Reporter: | Andrew Morrow (Inactive) | Assignee: | Michael Dirolf |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Ubuntu 10.04 x86_64 |
||
| Issue Links: |
|
||||||||
| Participants: | |||||||||
| Description |
|
An empty mainline, when linked with libmongoclient, then run under valgrind, reports a bad free at shutdown in __libc_freeres processing: mongo_libc_freeres$ cat ./main.cc int main(int argc, char* argv[]) mongo_libc_freeres$ g++ -ggdb ./main.cc -L /mongo.temp.install/lib64 -Wl,-rpath,/mongo.temp.install/lib64 -lmongoclient mongo_libc_freeres$ ls -la ./a.out mongo_libc_freeres$ ldd ./a.out mongo_libc_freeres$ valgrind --track-origins=yes --read-var-info=yes --leak-check=full ./a.out If we manually re-link libmongoclient.so without mozjs, the problem goes away (note lack of -lmozjs, and -L and -Wl,rpath arguments pointing to /usr/lib64/xulrunner-w.x.y.z: mongo$ g++ -o libmongoclient.so.9.9.9 -fPIC -pthread -rdynamic -Wl,-soname,libmongoclient.so.9.9.9 -shared pch.os buildinfo.os db/common.os db/jsobj.os db/json.os db/lasterror.os db/nonce.os db/queryutil.os shell/mongo.os util/background.os util/mmap.os util/ramstore.os util/sock.os util/util.os util/message.os util/assert_util.os util/httpclient.os util/md5main.os util/base64.os util/concurrency/vars.os util/concurrency/task.os util/debug_util.os util/concurrency/thread_pool.os util/password.os util/version.os util/histogram.os util/concurrency/spin_lock.os util/text.os util/md5.os client/connpool.os client/dbclient.os client/dbclientcursor.os client/model.os client/syncclusterconnection.os s/shardconnection.os util/mmap_posix.os util/processinfo_linux2.os client/clientOnly.os client/gridfs.os s/d_util.os -L/usr/lib64 -L/lib64 -lpthread -lstdc++ -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt -lboost_program_options-mt -lpcrecpp -lpcre mongo_libc_freeres$ ldd ./a.out (note that there is no link to libmozjs listed above) Re-running valgrind: mongo_libc_freeres$ valgrind --track-origins=yes --read-var-info=yes --leak-check=full ./a.out And our error goes away. Its pretty clear that libmongoclient doesn't actually depend on mozjs.so (since it linked), and forcing all clients that link against libmongoclient to pick up such a dependency seems to cause memory errors. It would be good if libmongoclient would drop this dependency. FWIW, libmongoclient links, on my system, the following libraries: -lpthread -lstdc++ -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt -lboost_program_options-mt -lpcrecpp -lpcre Many of these are not necessary: The explicit -lpthread is not needed since the g++ driver is being called with the -pthread option. Its better to let the compiler driver worry about where to put things like -lpthread and -lc on the link line. I verified that all of these can be removed by manually linking the library with -Wl,-zdefs added to the link line and removing each of the libraries, one by one. The final link line looked like: g++ -o libmongoclient.so.9.9.9 -fPIC -pthread -rdynamic -Wl,-zdefs -Wl,-soname,libmongoclient.so.9.9.9 -shared pch.os buildinfo.os db/common.os db/jsobj.os db/json.os db/lasterror.os db/nonce.os db/queryutil.os shell/mongo.os util/background.os util/mmap.os util/ramstore.os util/sock.os util/util.os util/message.os util/assert_util.os util/httpclient.os util/md5main.os util/base64.os util/concurrency/vars.os util/concurrency/task.os util/debug_util.os util/concurrency/thread_pool.os util/password.os util/version.os util/histogram.os util/concurrency/spin_lock.os util/text.os util/md5.os client/connpool.os client/dbclient.os client/dbclientcursor.os client/model.os client/syncclusterconnection.os s/shardconnection.os util/mmap_posix.os util/processinfo_linux2.os db/commands.os client/clientOnly.os client/gridfs.os s/d_util.os -L/usr/lib64 -L/lib64 -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt After this, my test mainline still runs cleanly, even with LD_BIND_NOW in the environment: mongo_libc_freeres$ LD_BIND_NOW=1 ./a.out And still shows no errors under valgrind. |
| Comments |
| Comment by Andrew Morrow (Inactive) [ 27/Jul/10 ] |
|
Yep, working great now. Thanks! |
| Comment by Michael Dirolf [ 27/Jul/10 ] |
|
there was a bug in the scons options handling where that invocation was not picking up the --full option. this should be fixed now, can you try again? thanks for the reports! |
| Comment by auto [ 27/Jul/10 ] |
|
Author: {'login': 'mdirolf', 'name': 'Mike Dirolf', 'email': 'mike@10gen.com'}Message: minor: use store_true for --sharedclient |
| Comment by Andrew Morrow (Inactive) [ 26/Jul/10 ] |
|
OK, I just tried: $ scons -c . ; scons -j 8 --prefix /home/acm/tmp/mongo-tmp-install --sharedclient --full install It does build libmongoclient.so in my current source dir, but neither it nor the headers make it to the prefix directory: $ cd /home/acm/tmp/mongo-tmp-install/ Can I send you some build log or are there SCons flags that would get debugging output that would be useful to you? I'm currently building from: http://github.com/mongodb/mongo/commit/127558c1c47f8df7fddd6a7408036eccdd3bf9ad Thanks. (And sorry for all the noise on this) |
| Comment by Michael Dirolf [ 26/Jul/10 ] |
|
You should still be able to build w/o building the separate client directory first (although that should work too). There was an issue with --full that I just fixed, so can you try again? Should be something like: scons --prefix whatever --sharedclient --full install |
| Comment by Andrew Morrow (Inactive) [ 26/Jul/10 ] |
|
RE: --as-needed: awesome. Thanks. RE building and packaging: I understand that its hard to get the build system working for everyone. But I'm confused about what I'm supposed to do to get a build that includes both libmongoclient.so and the BSON headers from the current git tree. Do I need to do a two stage build, where I first build something with '--prefix mongo-cxx-driver', and then build the driver from the resulting mongo-cxx-driver directory? Or should I still be able to build libmongoclient.so and the BSON headers directly from the tree? Because I've tried all sorts of variations of scons --prefix <something> --sharedclient --full <install|mongoclient> and in no case do I get both a shared libmongoclient.so and the client headers copied to the prefix directory, despite being built in the source tree. |
| Comment by auto [ 26/Jul/10 ] |
|
Author: {'login': 'erh', 'name': 'Eliot Horowitz', 'email': 'eliot@10gen.com'}Message: |
| Comment by Eliot Horowitz (Inactive) [ 26/Jul/10 ] |
|
The problem comes down to supporting a build system for an infinite number of use cases. I added At some point we'll need to do some build system cleaning - but its hard given the complexity. |
| Comment by Andrew Morrow (Inactive) [ 26/Jul/10 ] |
|
Hmm. That is unfortunate. It is unlikely that we are going to switch to using your client tarball, since we already build our own debian packages from your main source tree, onto which we rebase our changes for http://jira.mongodb.org/browse/SERVER-1257. I guess I don't really understand why creating a separate client tarball is a better solution than fixing the build system: we really want to be able to build mongo, in all facets, from one source tree, then package the build artifacts into separate server, client, and -dev debian packages. Anyway, I guess we can also maintain our preferred fix for this issue, which is to use |
| Comment by Michael Dirolf [ 26/Jul/10 ] |
|
Working on a fix for this now - thanks! Just as an FYI - the .so you get from a `scons --full --sharedclient install` will still link in libmozjs - to get around that you'll need to use the separate client tarball, see the case that eliot linked you to above. |
| Comment by Andrew Morrow (Inactive) [ 26/Jul/10 ] |
|
OK: 'scons --full install' does install the headers, libs, and binaries, but gets me a libmongoclient.a So I can't seem to get both a shared library, and the headers + libs. Any ideas? |
| Comment by Michael Dirolf [ 26/Jul/10 ] |
|
should be able to do http://github.com/mongodb/mongo/commit/b7358a8ea958a14c052cb5ca4ded2a6bcc8cb0e5 |
| Comment by Eliot Horowitz (Inactive) [ 26/Jul/10 ] |
|
We're going to add an option for a full/driver install in the main one. |
| Comment by Andrew Morrow (Inactive) [ 26/Jul/10 ] |
|
Ah. Is that why I suddenly can't get the mongo build system to install the libmongoclient header files unless I call my 'prefix' directory mongo-cxx-client? http://github.com/mongodb/mongo/blob/master/SConstruct#L494 That seems a bit restrictive. |
| Comment by Eliot Horowitz (Inactive) [ 26/Jul/10 ] |
|
We're going to package a separate c++ .tgz to keep things a bit cleaner for people who just want to use bson/c++ driver. |
| Comment by Andrew Morrow (Inactive) [ 26/Jul/10 ] |
|
I just tried to build client libraries against http://github.com/mongodb/mongo/commit/3083c08000747ec21ed5d723fa444ae698b4108a as follows: scons --prefix ~/tmp/mongo-tmp-install --release --nostrip --sharedclient mongoclient which is failing as follows: scons: Reading SConscript files ... I'm not sure why it would be looking for static versions of mozjs when building the shared client libraries. Also, I'm not sure what the 'new C++ driver thing / separate client tarball' comments are referring to. Thanks. |
| Comment by Michael Dirolf [ 26/Jul/10 ] |
|
no longer links in libmozjs w/ the separate client tarball. |
| Comment by Eliot Horowitz (Inactive) [ 24/Jul/10 ] |
|
With the new c++ driver thing - this should be automatic - but this is just a sanity check. |
| Comment by Andrew Morrow (Inactive) [ 01/Jul/10 ] |
|
So, obviously, this is really only a problem when building libmongoclient as a shared library. However, building it as a shared object is what we want to do, so: We looked into updating the sconscript so that libmongoclient didn't link libmozjs.so, but that turned out to be rather difficult given the architecture of the sconscript. As a workaround, at least when the linker is a binutils ld (bfd or gold), one solution is to add ' I'd recommend though, if building with So my recommended fix for this is to enable |