blob: 0575466b7192f478e3366d87f4a882c9ae8ebb51 [file] [log] [blame]
Author: Maks Orlovich <morlovich@google.com>
Description: Prevent crashes at startup with dynamically linked protobuf
--- a/src/net/instaweb/rewriter/process_context.cc
+++ b/src/net/instaweb/rewriter/process_context.cc
@@ -62,10 +62,10 @@
// starting up.
ShutDownCommandLineFlags();
- // The protobuf shutdown infrastructure is lazily initialized in a threadsafe
- // manner. See third_party/protobuf/src/google/protobuf/stubs/common.cc,
- // function InitShutdownFunctionsOnce.
+#if 0
+ // See comments in ApacheProcessContext ctor for why we can't use this here.
google::protobuf::ShutdownProtobufLibrary();
+#endif
url::Shutdown();
HtmlKeywords::ShutDown();
--- a/src/net/instaweb/mod_pagespeed.gyp
+++ b/src/net/instaweb/mod_pagespeed.gyp
@@ -29,6 +29,9 @@
'dependencies+': [
'<(DEPTH)/third_party/httpd/httpd.gyp:include',
],
+ 'libraries': [
+ '-ldl',
+ ],
},
{
'target_name': 'mod_pagespeed_ap24',
--- a/src/pagespeed/apache/mod_instaweb.cc
+++ b/src/pagespeed/apache/mod_instaweb.cc
@@ -19,6 +19,7 @@
// that mod_pagespeed needs to do to be an Apache module.
#include <unistd.h>
+#include <dlfcn.h>
#include <cerrno>
#include <cstddef>
@@ -304,6 +305,27 @@
class ApacheProcessContext {
public:
ApacheProcessContext() : apache_cmds_(NULL) {
+ // One of our dependencies is Protocol Buffers. Dynamically linking
+ // to them causes a problem if the following sequence of steps happens:
+ //
+ // 1) unload mod_pagespeed.so
+ // 2) libprotobuf.so sticks around.
+ // 3) load mod_pagespeed.so again
+ //
+ // When that occurs, a lot of global state ends up being out of sync
+ // between the two .so's regardless of what we do.
+ //
+ // Oh, and w/o this patch, this happens at server startup. Steps 1 and 3
+ // happen because this is just how Apache + apr work. Step 2 is because it
+ // turns out that libprotobuf triggers something called STB_GNU_UNIQUE,
+ // which, among other things, prevents the library from being unloaded.
+ // (Even if that wasn't there, another client could potentially keep
+ // libprotobuf.so around just via refcount).
+ //
+ // The result being, we can't let ourselves be unloaded... so this asks
+ // the dynamic linker to bump the refcount... and sadly hardcodes our path.
+ dlopen("/usr/lib/apache2/modules/mod_pagespeed.so", RTLD_GLOBAL | RTLD_NOW);
+
ApacheRewriteDriverFactory::Initialize();
InstallCommands();
}