]> granicus.if.org Git - icinga2/commitdiff
Fix static initializer priority for namespaces in LTO builds 6591/head
authorMichael Friedrich <michael.friedrich@icinga.com>
Tue, 4 Sep 2018 13:17:34 +0000 (13:17 +0000)
committerMichael Friedrich <michael.friedrich@icinga.com>
Tue, 4 Sep 2018 14:36:22 +0000 (16:36 +0200)
fixes #6575

lib/base/function.hpp
lib/base/objecttype.cpp
lib/base/primitivetype.hpp
lib/base/scriptframe.cpp
lib/base/type.cpp
lib/base/type.hpp
lib/cli/daemonutility.cpp
lib/config/configfragment.hpp
lib/icinga/icingaapplication.cpp

index 493be13ee93b477b7a9130dd81a9737e12d26082..3eb7ce98d497cd61316228e72b9ad2abaa688681 100644 (file)
@@ -72,6 +72,7 @@ private:
                bool side_effect_free, bool deprecated);
 };
 
+/* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
 #define REGISTER_FUNCTION(ns, name, callback, args) \
        INITIALIZE_ONCE_WITH_PRIORITY([]() { \
                Function::Ptr sf = new icinga::Function(#ns "#" #name, callback, String(args).Split(":"), false); \
index d77bfcdaeb570aebfee171d3ae32b40d61439860..eff6696c96caa5ac4c2f48f5e181a9841d3253f2 100644 (file)
@@ -23,6 +23,7 @@
 
 using namespace icinga;
 
+/* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
 INITIALIZE_ONCE_WITH_PRIORITY([]() {
        Type::Ptr type = new ObjectType();
        type->SetPrototype(Object::GetPrototype());
index 45ae8411aa85ead897222baf7bf635954c79d49c..61cedb6cb545d3e89ffa1e4a40499825e3c4fdf9 100644 (file)
@@ -48,6 +48,7 @@ private:
        ObjectFactory m_Factory;
 };
 
+/* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
 #define REGISTER_BUILTIN_TYPE(type, prototype)                                 \
        INITIALIZE_ONCE_WITH_PRIORITY([]() {                                    \
                icinga::Type::Ptr t = new PrimitiveType(#type, "None");         \
index 90407613efa27a345592b20b32798355d9cb7d9e..36f75284ed3e7e4cf76a7f9ad88f6d9a79692b44 100644 (file)
@@ -29,6 +29,10 @@ boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFram
 
 static auto l_InternalNSBehavior = new ConstNamespaceBehavior();
 
+/* Ensure that this gets called with highest priority
+ * and wins against other static initializers in lib/icinga, etc.
+ * LTO-enabled builds will cause trouble otherwise, see GH #6575.
+ */
 INITIALIZE_ONCE_WITH_PRIORITY([]() {
        Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
 
@@ -51,7 +55,7 @@ INITIALIZE_ONCE_WITH_PRIORITY([]() {
 
        Namespace::Ptr internalNS = new Namespace(l_InternalNSBehavior);
        globalNS->SetAttribute("Internal", std::make_shared<ConstEmbeddedNamespaceValue>(internalNS));
-}, 50);
+}, 1000);
 
 INITIALIZE_ONCE_WITH_PRIORITY([]() {
        l_InternalNSBehavior->Freeze();
index b8bddd7fb60ddbff6536978adf8831004f1cf4b3..a010d55a0f0c01f04df994d1f45964d943e0527e 100644 (file)
@@ -26,6 +26,7 @@ using namespace icinga;
 
 Type::Ptr Type::TypeInstance;
 
+/* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
 INITIALIZE_ONCE_WITH_PRIORITY([]() {
        Type::Ptr type = new TypeType();
        type->SetPrototype(TypeType::GetPrototype());
index ef8ce6d231abbada0f6ea165037f2bdd2765a2d2..a8fb7dc8987879b0f1c6bc3479298bcb8b1ed3dc 100644 (file)
@@ -138,6 +138,7 @@ class TypeImpl
 {
 };
 
+/* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
 #define REGISTER_TYPE(type) \
        INITIALIZE_ONCE_WITH_PRIORITY([]() { \
                icinga::Type::Ptr t = new TypeImpl<type>(); \
index ea1630c8ad9083ac313179f505b5ff75ede7f7b4..cddbf4ec57817cfc5377c4a2d7146fb539edd521 100644 (file)
 #include "base/utility.hpp"
 #include "base/logger.hpp"
 #include "base/application.hpp"
+#include "base/scriptglobal.hpp"
 #include "config/configcompiler.hpp"
 #include "config/configcompilercontext.hpp"
 #include "config/configitembuilder.hpp"
 
-
 using namespace icinga;
 
 static bool ExecuteExpression(Expression *expression)
@@ -146,6 +146,9 @@ bool DaemonUtility::ValidateConfigFiles(const std::vector<std::string>& configs,
                return false;
 
        Namespace::Ptr systemNS = ScriptGlobal::Get("System");
+       VERIFY(systemNS);
+
+       /* This is initialized inside the IcingaApplication class. */
        Value vAppType;
        VERIFY(systemNS->Get("ApplicationType", &vAppType));
 
index bd3c5939baf2dae937bc8c03d6157ab797a7edca..cbc7727372e6c9669f1596c259177df7ba658ad5 100644 (file)
@@ -26,6 +26,7 @@
 #include "base/exception.hpp"
 #include "base/application.hpp"
 
+/* Ensure that the priority is lower than the basic namespace initialization in scriptframe.cpp. */
 #define REGISTER_CONFIG_FRAGMENT(name, fragment) \
        INITIALIZE_ONCE_WITH_PRIORITY([]() { \
                std::unique_ptr<icinga::Expression> expression = icinga::ConfigCompiler::CompileText(name, fragment); \
index 28ca04bbd724a48b79ef7de4347df913f0194247..a8d7104b3123c4b51d4c412a84e02a7953388dd4 100644 (file)
@@ -41,6 +41,7 @@ using namespace icinga;
 static Timer::Ptr l_RetentionTimer;
 
 REGISTER_TYPE(IcingaApplication);
+/* Ensure that the priority is lower than the basic System namespace initialization in scriptframe.cpp. */
 INITIALIZE_ONCE_WITH_PRIORITY(&IcingaApplication::StaticInitialize, 50);
 
 void IcingaApplication::StaticInitialize()
@@ -59,11 +60,15 @@ void IcingaApplication::StaticInitialize()
 
        ScriptGlobal::Set("NodeName", node_name);
 
-       ScriptGlobal::Set("System.ApplicationType", "IcingaApplication", true);
+       Namespace::Ptr systemNS = ScriptGlobal::Get("System");
+       /* Ensure that the System namespace is already initialized. Otherwise this is a programming error. */
+       VERIFY(systemNS);
 
-       ScriptGlobal::Set("System.ApplicationVersion", Application::GetAppVersion(), true);
+       systemNS->Set("ApplicationType", "IcingaApplication", true);
+       systemNS->Set("ApplicationVersion", Application::GetAppVersion(), true);
 
        Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
+       VERIFY(globalNS);
 
        auto icingaNSBehavior = new ConstNamespaceBehavior();
        icingaNSBehavior->Freeze();