Merge remote-tracking branch 'origin/topic/johanna/component-initialization-order'

* origin/topic/johanna/component-initialization-order:
  Make tags generated during component initialization stable.
This commit is contained in:
Johanna Amann 2016-08-11 21:49:06 -07:00
commit fb3bc05df5
15 changed files with 118 additions and 13 deletions

12
CHANGES
View file

@ -1,4 +1,16 @@
2.4-927 | 2016-08-11 21:49:06 -0700
* Make component tags generated during component initialization stable.
Before, it was dependent on the order a compiler called constructors.
This makes a few tests work with gcc. (Johanna Amann)
* Make x509 intel seen script more robust (Johanna Amann)
* Input: DisableFrontend was not called upon Init failure. (Johanna Amann)
* DCE_RPC code simplification. (Seth Hall)
2.4-921 | 2016-08-10 20:29:48 -0700
* Add logging framework ext-data mechanism. It is now possible to

View file

@ -1 +1 @@
2.4-921
2.4-927

View file

@ -15,7 +15,11 @@ Component::Component(const std::string& name, factory_callback arg_factory, Tag:
factory = arg_factory;
enabled = arg_enabled;
partial = arg_partial;
}
void Component::Initialize()
{
InitializeTag();
analyzer_mgr->RegisterComponent(this, "ANALYZER_");
}

View file

@ -63,6 +63,13 @@ public:
*/
~Component();
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the analyzer's factory function.
*/
@ -93,7 +100,7 @@ protected:
/**
* Overriden from plugin::Component.
*/
virtual void DoDescribe(ODesc* d) const;
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory; // The analyzer's factory callback.

View file

@ -13,7 +13,11 @@ Component::Component(const std::string& name, factory_callback arg_factory, Tag:
plugin::TaggedComponent<file_analysis::Tag>(subtype)
{
factory = arg_factory;
}
void Component::Initialize()
{
InitializeTag();
file_mgr->RegisterComponent(this, "ANALYZER_");
}

View file

@ -54,6 +54,13 @@ public:
*/
~Component();
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the analyzer's factory function.
*/
@ -63,7 +70,7 @@ protected:
/**
* Overriden from plugin::Component.
*/
virtual void DoDescribe(ODesc* d) const;
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory; // The analyzer's factory callback.

View file

@ -12,7 +12,11 @@ Component::Component(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::READER, name)
{
factory = arg_factory;
}
void Component::Initialize()
{
InitializeTag();
input_mgr->RegisterComponent(this, "READER_");
}

View file

@ -39,6 +39,13 @@ public:
*/
~Component();
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the reader's factory function.
*/
@ -48,7 +55,7 @@ protected:
/**
* Overriden from plugin::Component.
*/
virtual void DoDescribe(ODesc* d) const;
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory;

View file

@ -11,7 +11,11 @@ Component::Component(const std::string& name, factory_callback arg_factory)
: plugin::Component(plugin::component::WRITER, name)
{
factory = arg_factory;
}
void Component::Initialize()
{
InitializeTag();
log_mgr->RegisterComponent(this, "WRITER_");
}

View file

@ -39,6 +39,13 @@ public:
*/
~Component();
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it is used to add the
* plugin component to the list of components and to initialize tags
*/
void Initialize() override;
/**
* Returns the writer's factory function.
*/
@ -48,7 +55,7 @@ protected:
/**
* Overriden from plugin::Component.
*/
virtual void DoDescribe(ODesc* d) const;
void DoDescribe(ODesc* d) const override;
private:
factory_callback factory;

View file

@ -48,6 +48,13 @@ public:
*/
virtual ~Component();
/**
* Initialization function. This function has to be called before any
* plugin component functionality is used; it commonly is used to add the
* plugin component to the list of components and to initialize tags
*/
virtual void Initialize() {}
/**
* Returns the compoment's type.
*/

View file

@ -238,6 +238,7 @@ bool Manager::ActivateDynamicPluginInternal(const std::string& name, bool ok_if_
current_plugin->SetDynamic(true);
current_plugin->DoConfigure();
current_plugin->InitializeComponents();
if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION )
reporter->FatalError("plugin's API version does not match Bro (expected %d, got %d in %s)",
@ -328,9 +329,6 @@ void Manager::RegisterPlugin(Plugin *plugin)
// A dynamic plugin, record its location.
plugin->SetPluginLocation(current_dir, current_sopath);
// Sort plugins by name to make sure we have a deterministic order.
ActivePluginsInternal()->sort(plugin_cmp);
current_plugin = plugin;
}
@ -354,9 +352,21 @@ void Manager::InitPreScript()
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
i != Manager::ActivePluginsInternal()->end(); i++ )
{
Plugin* plugin = *i;
plugin->DoConfigure();
plugin->InitPreScript();
(*i)->DoConfigure();
}
// Sort plugins by name to make sure we have a deterministic order.
// We cannot do this before, because the plugin name (used for plugin_cmp) is only
// set in DoConfigure.
// We need things sorted to generate the tags (in InitializeComponents) in a deterministic
// order.
ActivePluginsInternal()->sort(plugin_cmp);
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
i != Manager::ActivePluginsInternal()->end(); i++ )
{
(*i)->InitializeComponents();
(*i)->InitPreScript();
}
init = true;

View file

@ -327,6 +327,12 @@ void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgum
{
}
void Plugin::InitializeComponents()
{
for ( component_list::const_iterator i = components.begin(); i != components.end(); i++ )
(*i)->Initialize();
}
void Plugin::Describe(ODesc* d) const
{
d->Add(config.name);

View file

@ -492,12 +492,17 @@ protected:
virtual void Done();
/**
* Registers and activates a component.
* Registers a component.
*
* @param c The component. The method takes ownership.
*/
void AddComponent(Component* c);
/**
* Calls the Initialize() function of all components.
*/
void InitializeComponents();
/**
* Enables a hook. The corresponding virtual method will now be
* called as Bro's processing proceeds. Note that enabling hooks can

View file

@ -13,7 +13,9 @@ class TaggedComponent {
public:
/**
* Constructor creates a unique tag value for this component.
* Constructor for TaggedComponend. Note that a unique value
* for this component is only created when InitializeTag is
* called.
*
* @param subtype A subtype associated with this component that
* further distinguishes it. The subtype will be integrated into
@ -23,6 +25,12 @@ public:
*/
TaggedComponent(typename T::subtype_t subtype = 0);
/**
* Initializes tag by creating the unique tag value for thos componend.
* Has to be called exactly once.
*/
void InitializeTag();
/**
* @return The component's tag.
*/
@ -30,6 +38,8 @@ public:
private:
T tag; /**< The automatically assigned analyzer tag. */
typename T::subtype_t subtype;
bool initialized;
static typename T::type_t type_counter; /**< Used to generate globally
unique tags. */
};
@ -37,12 +47,23 @@ private:
template <class T>
TaggedComponent<T>::TaggedComponent(typename T::subtype_t subtype)
{
tag = T(1,0);
this->subtype = subtype;
initialized = false;
}
template <class T>
void TaggedComponent<T>::InitializeTag()
{
assert( initialized == false );
initialized = true;
tag = T(++type_counter, subtype);
}
template <class T>
T TaggedComponent<T>::Tag() const
{
assert( initialized );
return tag;
}