Skip to content

Commit b9f932b

Browse files
hanumantmkacmorrow
authored andcommitted
CXX-123 force inits at link w/ static archive
force inclusion of translation units with MONGO_INITIAILIZERS when linking with the static archive by adding magic symbols into relevant cpp files that are referenced from base/initializer.cpp This prevents unreferenced initiailizers from getting dropped, which obviously screws up behavior
1 parent 20bdfd9 commit b9f932b

16 files changed

+75
-9
lines changed

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ the server sources: this repo is the only approved source for driver builds.
99

1010
## Components
1111

12-
libmongoclient.[so|dylib|dll] - The shared mongoclient library
13-
libmongoclient.a - The static mongoclient library (but see notes)
12+
libmongoclient.[so|dylib|dll] - The shared mongoclient library (but see notes)
13+
libmongoclient.a - The static mongoclient library
1414

1515
## Building
1616

@@ -21,11 +21,11 @@ the server sources: this repo is the only approved source for driver builds.
2121

2222
## Notes
2323

24-
Use of the static library is discouraged, and support may be removed soon. To properly
25-
link against the static library on ELF platforms, you must link it with the
26-
--whole-archive flag to ld. The static library is not useable on Windows since
27-
there is no analogue to --whole-archive. The static library may work on OS X, but
28-
we still strongly recommend using the dynamic library.
24+
Use of the shared library is experimental on windows and is currently
25+
discouraged. This is primarily due to the complexity of ensuring a matching
26+
implementation of STL types between library and consumer code. This problem
27+
is unique to windows, as the consistent use of system libraries largely
28+
mitigates this danger.
2929

3030
## Documentation
3131

SConstruct

+4
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,10 @@ def doConfigure(myenv):
14101410
conf.FindSysLibDep( "v8", v8_lib_choices )
14111411

14121412
conf.env['MONGO_BUILD_SASL_CLIENT'] = bool(has_option("use-sasl-client"))
1413+
1414+
if conf.env['MONGO_BUILD_SASL_CLIENT']:
1415+
env.Append( CPPDEFINES=["MONGO_SASL"] )
1416+
14131417
if conf.env['MONGO_BUILD_SASL_CLIENT'] and not conf.CheckLibWithHeader(
14141418
"sasl2",
14151419
["stddef.h","sasl/sasl.h"],

src/mongo/base/init.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@
1616
#include "mongo/base/init.h"
1717

1818
MONGO_INITIALIZER_GROUP(default, MONGO_NO_PREREQUISITES, MONGO_NO_DEPENDENTS)
19+
20+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(base_init)

src/mongo/base/init.h

+3
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,6 @@
130130
* named "NAME".
131131
*/
132132
#define _MONGO_INITIALIZER_FUNCTION_NAME(NAME) _mongoInitializerFunction_##NAME
133+
134+
#define MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(NAME) \
135+
namespace mongo { void _mongoInitializerFunctionAssure_##NAME() {} }

src/mongo/base/initializer.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,29 @@ namespace mongo {
2424
Initializer::Initializer() {}
2525
Initializer::~Initializer() {}
2626

27+
/* This array of function pointers is necessary to force inclusion of
28+
* translation units with global initializers when linking against a static
29+
* archive version of the client. In their absence, the related code may
30+
* resolve no symbols in a potential output binary, failing to pull in the
31+
* initializers and leaving the client in a broken state.
32+
*
33+
* Working around this with --whole-archive or an equivalent is painful where
34+
* possible and renders the static archive useless where not possible (on
35+
* windows).
36+
*
37+
* Sorry for the hack...
38+
*/
39+
#define INSTALL_FUNCTION(NAME) void _mongoInitializerFunctionAssure_##NAME();
40+
#include "mongo/base/initializer_functions.h"
41+
#undef INSTALL_FUNCTION
42+
43+
void (* _mongoGlobalInitializers [])() = {
44+
#define INSTALL_FUNCTION(NAME) &(_mongoInitializerFunctionAssure_##NAME),
45+
#include "mongo/base/initializer_functions.h"
46+
#undef INSTALL_FUNCTION
47+
NULL
48+
};
49+
2750
Status Initializer::execute(const InitializerContext::ArgumentVector& args,
2851
const InitializerContext::EnvironmentMap& env) const {
2952

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
INSTALL_FUNCTION(base_init) // "default"
2+
INSTALL_FUNCTION(platform_backtrace) // "SolarisBacktrace"
3+
INSTALL_FUNCTION(logger_logstream_builder) // "LogstreamBuilder"
4+
INSTALL_FUNCTION(logger_ramlog) // "RamLogCatalog"
5+
INSTALL_FUNCTION(logger_logger) // "GlobalLogManager"
6+
#ifdef MONGO_SASL
7+
INSTALL_FUNCTION(client_sasl_client_authenticate_impl) // "SaslClientAuthenticateFunction"
8+
INSTALL_FUNCTION(client_sasl_client_session) // "CyrusSaslAllocatorsAndMutexes,SaslClientContext"
9+
INSTALL_FUNCTION(client_sasl_sspi) // "SaslSspiClientPlugin,SaslCramClientPlugin,SaslPlainClientPlugin"
10+
#endif
11+
INSTALL_FUNCTION(util_fail_point_service) // "FailPointRegistry,AllFailPointsRegistered"
12+
INSTALL_FUNCTION(util_net_socket_poll) // "DynamicLinkWin32Poll"
13+
INSTALL_FUNCTION(util_net_ssl_manager) // "SSLManager"

src/mongo/client/sasl_client_authenticate_impl.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,5 @@ namespace {
251251

252252
} // namespace
253253
} // namespace mongo
254+
255+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(client_sasl_client_authenticate_impl)

src/mongo/client/sasl_client_session.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,5 @@ namespace {
317317
}
318318

319319
} // namespace mongo
320+
321+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(client_sasl_client_session)

src/mongo/client/sasl_sspi.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
#include "mongo/base/init.h"
18+
1719
#ifdef _WIN32
1820

1921
#define SECURITY_WIN32 1 // Required for SSPI support.
@@ -25,7 +27,6 @@
2527
#include <sasl/saslplug.h>
2628
#include <sspi.h>
2729

28-
#include "mongo/base/init.h"
2930
#include "mongo/util/mongoutils/str.h"
3031
#include "mongo/base/status.h"
3132
#include "mongo/util/scopeguard.h"
@@ -527,3 +528,5 @@ namespace {
527528
} // namespace mongo
528529

529530
#endif // ifdef _WIN32
531+
532+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(client_sasl_sspi)

src/mongo/logger/logger.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,5 @@ namespace logger {
5252

5353
} // namespace logger
5454
} // namespace mongo
55+
56+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(logger_logger)

src/mongo/logger/logstream_builder.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,5 @@ namespace logger {
132132

133133
} // namespace logger
134134
} // namespace mongo
135+
136+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(logger_logstream_builder)

src/mongo/logger/ramlog.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,5 @@ namespace {
245245
return Status::OK();
246246
}
247247
}
248+
249+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(logger_ramlog)

src/mongo/platform/backtrace.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* limitations under the License.
1414
*/
1515

16+
#include "mongo/base/init.h"
17+
1618
#if !defined(_WIN32)
1719
#if defined(__sunos__) || !defined(MONGO_HAVE_EXECINFO_BACKTRACE)
1820

@@ -25,7 +27,6 @@
2527
#include <ucontext.h>
2628
#include <vector>
2729

28-
#include "mongo/base/init.h"
2930
#include "mongo/base/status.h"
3031

3132
using std::string;
@@ -213,3 +214,5 @@ namespace {
213214

214215
#endif // #if defined(__sunos__)
215216
#endif // #if !defined(_WIN32)
217+
218+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(platform_backtrace)

src/mongo/util/fail_point_service.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ namespace mongo {
3636
return _fpRegistry.get();
3737
}
3838
}
39+
40+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(util_fail_point_service)

src/mongo/util/net/socket_poll.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ namespace mongo {
6060

6161

6262

63+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(util_net_socket_poll)

src/mongo/util/net/ssl_manager.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -930,3 +930,5 @@ namespace mongo {
930930
}
931931
#endif // #ifdef MONGO_SSL
932932
}
933+
934+
MONGO_INITIALIZER_FUNCTION_ASSURE_FILE(util_net_ssl_manager)

0 commit comments

Comments
 (0)