From b40f9038d2527cecbc07a4abdf792231b82db244 Mon Sep 17 00:00:00 2001 From: Andrew Morrow Date: Wed, 7 Apr 2021 17:23:16 -0400 Subject: SERVER-55737 Add an experiment for not requiring -rdynamic --- SConstruct | 46 ++++++++++++++++++++++++++++++-------- src/mongo/util/SConscript | 3 +++ src/mongo/util/stacktrace_test.cpp | 16 ++++++++----- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/SConstruct b/SConstruct index 04eaa5bcff5..9e4cad24503 100644 --- a/SConstruct +++ b/SConstruct @@ -277,6 +277,7 @@ experimental_optimizations = [ 'builtin-memcmp', 'fnsi', 'nofp', + 'nordyn', 'sandybridge', 'tbaa', 'treevec', @@ -2561,21 +2562,48 @@ if env.TargetOSIs('posix'): # SERVER-9761: Ensure early detection of missing symbols in dependent libraries at program # startup. - if env.TargetOSIs('darwin'): - if env.TargetOSIs('macOS'): - env.Append( LINKFLAGS=["-Wl,-bind_at_load"] ) - else: + env.Append( + LINKFLAGS=[ + "-Wl,-bind_at_load" if env.TargetOSIs('macOS') else "-Wl,-z,now", + ], + ) + + # We need to use rdynamic for backtraces with glibc unless we have libunwind. + nordyn = (env.TargetOSIs('darwin') or use_libunwind) + + # And of course only do rdyn if the experimenter asked for it. + nordyn &= ("nordyn" in selected_experimental_optimizations) + + if nordyn: + def export_symbol_generator(source, target, env, for_signature): + symbols = copy.copy(env.get('EXPORT_SYMBOLS', [])) + for lib in libdeps.get_libdeps(source, target, env, for_signature): + if lib.env: + symbols.extend(lib.env.get('EXPORT_SYMBOLS', [])) + export_expansion = '${EXPORT_SYMBOL_FLAG}' + return [f'-Wl,{export_expansion}{symbol}' for symbol in symbols] + env['EXPORT_SYMBOL_GEN'] = export_symbol_generator + + # For darwin, we need the leading underscore but for others we + # don't. Hacky but it works to jam that distinction into the + # flag itself, since it already differs on darwin. + if env.TargetOSIs('darwin'): + env['EXPORT_SYMBOL_FLAG'] = "-exported_symbol,_" + else: + env['EXPORT_SYMBOL_FLAG'] = "--export-dynamic-symbol," + env.Append( - LINKFLAGS=[ - "-Wl,-z,now", + PROGLINKFLAGS=[ + '$EXPORT_SYMBOL_GEN' ], + ) + elif not env.TargetOSIs('darwin'): + env.Append( PROGLINKFLAGS=[ "-rdynamic", - ] + ], ) - env.Append( LIBS=[] ) - #make scons colorgcc friendly for key in ('HOME', 'TERM'): try: diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript index 681207594db..ee75e3724f5 100644 --- a/src/mongo/util/SConscript +++ b/src/mongo/util/SConscript @@ -761,6 +761,9 @@ stacktraceEnv.CppUnitTest( 'stacktrace_test.cpp', ], LIBDEPS=stacktrace_test_LIBDEPS, + EXPORT_SYMBOLS=[ + 'mongo_stacktrace_test_detail_testFunctionWithLinkage', + ], ) stacktraceEnv.Benchmark( diff --git a/src/mongo/util/stacktrace_test.cpp b/src/mongo/util/stacktrace_test.cpp index feac7aa72aa..2a9ad180c28 100644 --- a/src/mongo/util/stacktrace_test.cpp +++ b/src/mongo/util/stacktrace_test.cpp @@ -69,13 +69,17 @@ #include #endif // __linux__ +// Needs to have linkage so we can test metadata. Needs to be extern +// "C" so it doesn't get mangled so we can name it with EXPORT_SYMBOLS +// in SConscript. +extern "C" MONGO_COMPILER_NOINLINE MONGO_COMPILER_API_EXPORT void +mongo_stacktrace_test_detail_testFunctionWithLinkage() { + printf("..."); +} + namespace mongo { namespace stack_trace_test_detail { -/** Needs to have linkage so we can test metadata. */ -MONGO_COMPILER_NOINLINE MONGO_COMPILER_API_EXPORT void testFunctionWithLinkage() { - printf("..."); -} struct RecursionParam { std::uint64_t n; @@ -320,7 +324,7 @@ TEST(StackTrace, MetadataGenerator) { std::string symbolSub; } const tests[] = { { - reinterpret_cast(&stack_trace_test_detail::testFunctionWithLinkage), + reinterpret_cast(&mongo_stacktrace_test_detail_testFunctionWithLinkage), "stacktrace_test", "testFunctionWithLinkage", }, @@ -356,7 +360,7 @@ TEST(StackTrace, MetadataGeneratorFunctionMeasure) { // Measure the size of a C++ function as a test of metadata retrieval. // Load increasing addresses until the metadata's symbol name changes. StackTraceAddressMetadataGenerator gen; - void* fp = reinterpret_cast(&stack_trace_test_detail::testFunctionWithLinkage); + void* fp = reinterpret_cast(&mongo_stacktrace_test_detail_testFunctionWithLinkage); const auto& meta = gen.load(fp); if (!meta.symbol()) return; // No symbol for `fp`. forget it. -- cgit v1.2.1