[SERVER-49141] Coverity build of mongodb/mongo failing with link error for libunwind Created: 26/Jun/20 Updated: 29/Oct/23 Resolved: 29/Jun/20 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Build |
| Affects Version/s: | None |
| Fix Version/s: | 4.7.0 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Eric Milkie | Assignee: | Andrew Morrow (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||
| Backwards Compatibility: | Fully Compatible | ||||||||||||||||
| Operating System: | ALL | ||||||||||||||||
| Sprint: | Dev Platform 2020-06-29, Dev Platform 2020-07-13 | ||||||||||||||||
| Participants: | |||||||||||||||||
| Linked BF Score: | 0 | ||||||||||||||||
| Description |
|
Coverity builds with this command line: /usr/local/bin/python3 buildscripts/scons.py --install-mode=hygienic install-all --keep-going --variables-files=etc/scons/mongodbtoolchain_stable_gcc.vars --disable-warnings-as-errors -j6 --opt=off --dbg=off --allocator=system --link-model=dynamic
And as of last night, ran a build at the head of mongodb main branch and encountered this linker error:
|
| Comments |
| Comment by Githook User [ 29/Jun/20 ] |
|
Author: {'name': 'Andrew Morrow', 'email': 'acm@mongodb.com', 'username': 'acmorrow'}Message: |
| Comment by Andrew Morrow (Inactive) [ 26/Jun/20 ] |
|
This was caused by the changes in At its simplest, the cause here is that when building in --link-model=dynamic --allocator=system the stacktrace_bm target doesn't end up with libunwind on its link line, as it clearly must always have if it is going to link, since it directly uses symbols from the library. A quick look suggests that the answer is simple: This leads to an obvious question of why such a clear error didn't fail either the ! Shared Library Enterprise RHEL 6.2 builders compile_all task, or the Enterprise RHEL 6.2 (Benchmarks) builders compile_benchmarks task. The latter is easily answered: the Benchmarks builder builds in static mode, not dynamic. It also implicitly uses --allocator=tcmalloc, and ultimately the tcmalloc_minimal library has a dependency on libunwind. Since the PUBLIC/PRIVATE distinction doesn't exist in static builds, the link of stacktrace_bm includes libunwind via transitivity, and everything works. The former case is much more interesting. If libunwind has been made LIBDEPS_PRIVATE to both base and tcmalloc_minimal, how could stacktrace_bm have linked at all? Since we are using --link-model=dynamic, LIBDEPS_PRIVATE is enabled, and libunwind should not appear on the link line for stacktrace_bm, so we would expect the link to fail. But when we examine the logs, we find that, somehow libunwind does appear on the link line for stacktrace_bm. So everything links just fine. The important clue is that if you switch the build to use --allocator=system --link-model=dynamic, suddenly the test breaks. So, despite the fact that after Searching for all instances of shim_unwind provides the answer. The behavior of env.InjectThirdParty(libraries=['unwind']), which is used in the Environment setup for both base and tcmalloc_minimal sets LIBDEPS to ['$BUILD_DIR/third_party/shim_unwind'], effectively making the unwind dependency a public LIBDEP in the affected Environment. But if that were the whole story, then shim_unwind would have become a public LIBDEP for libbase and stacktrace_bm should have linked! Which brings in the last piece. The Library declaration for base has explicit LIBDEPS and LIBDEPS_PRIVATE overrides in its environment. So the LIBDEPS value set by env.InjectThirdParty(libraries=['unwind']) is overwritten and ignored. So unwind remains a private LIBDEP of base: linking only to base won't get you unwind. But the Library declaration for tcmalloc_minimal only has an override for LIBDEPS_PRIVATE, so the LIBDEPS value injected by env.InjectThirdParty(libraries=['unwind']), remains effective: unwind is LIBDEPS_PUBLIC in tcmalloc_minimal (and also LIBDEPS_PRIVATE, which is why There are several lessons to learn from this:
The immediate fix for the issue is straightforward. We will remove the modification of LIBDEPS from the behavior of env.InjectThirdParty(libraries=['unwind']), and directly attach shim_unwind in all the required places. |