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 2.4-921 | 2016-08-10 20:29:48 -0700
* Add logging framework ext-data mechanism. It is now possible to * 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; factory = arg_factory;
enabled = arg_enabled; enabled = arg_enabled;
partial = arg_partial; partial = arg_partial;
}
void Component::Initialize()
{
InitializeTag();
analyzer_mgr->RegisterComponent(this, "ANALYZER_"); analyzer_mgr->RegisterComponent(this, "ANALYZER_");
} }

View file

@ -63,6 +63,13 @@ public:
*/ */
~Component(); ~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. * Returns the analyzer's factory function.
*/ */
@ -93,7 +100,7 @@ protected:
/** /**
* Overriden from plugin::Component. * Overriden from plugin::Component.
*/ */
virtual void DoDescribe(ODesc* d) const; void DoDescribe(ODesc* d) const override;
private: private:
factory_callback factory; // The analyzer's factory callback. 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) plugin::TaggedComponent<file_analysis::Tag>(subtype)
{ {
factory = arg_factory; factory = arg_factory;
}
void Component::Initialize()
{
InitializeTag();
file_mgr->RegisterComponent(this, "ANALYZER_"); file_mgr->RegisterComponent(this, "ANALYZER_");
} }

View file

@ -54,6 +54,13 @@ public:
*/ */
~Component(); ~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. * Returns the analyzer's factory function.
*/ */
@ -63,7 +70,7 @@ protected:
/** /**
* Overriden from plugin::Component. * Overriden from plugin::Component.
*/ */
virtual void DoDescribe(ODesc* d) const; void DoDescribe(ODesc* d) const override;
private: private:
factory_callback factory; // The analyzer's factory callback. 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) : plugin::Component(plugin::component::READER, name)
{ {
factory = arg_factory; factory = arg_factory;
}
void Component::Initialize()
{
InitializeTag();
input_mgr->RegisterComponent(this, "READER_"); input_mgr->RegisterComponent(this, "READER_");
} }

View file

@ -39,6 +39,13 @@ public:
*/ */
~Component(); ~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. * Returns the reader's factory function.
*/ */
@ -48,7 +55,7 @@ protected:
/** /**
* Overriden from plugin::Component. * Overriden from plugin::Component.
*/ */
virtual void DoDescribe(ODesc* d) const; void DoDescribe(ODesc* d) const override;
private: private:
factory_callback factory; 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) : plugin::Component(plugin::component::WRITER, name)
{ {
factory = arg_factory; factory = arg_factory;
}
void Component::Initialize()
{
InitializeTag();
log_mgr->RegisterComponent(this, "WRITER_"); log_mgr->RegisterComponent(this, "WRITER_");
} }

View file

@ -39,6 +39,13 @@ public:
*/ */
~Component(); ~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. * Returns the writer's factory function.
*/ */
@ -48,7 +55,7 @@ protected:
/** /**
* Overriden from plugin::Component. * Overriden from plugin::Component.
*/ */
virtual void DoDescribe(ODesc* d) const; void DoDescribe(ODesc* d) const override;
private: private:
factory_callback factory; factory_callback factory;

View file

@ -48,6 +48,13 @@ public:
*/ */
virtual ~Component(); 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. * 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->SetDynamic(true);
current_plugin->DoConfigure(); current_plugin->DoConfigure();
current_plugin->InitializeComponents();
if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION ) if ( current_plugin->APIVersion() != BRO_PLUGIN_API_VERSION )
reporter->FatalError("plugin's API version does not match Bro (expected %d, got %d in %s)", 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. // A dynamic plugin, record its location.
plugin->SetPluginLocation(current_dir, current_sopath); 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; current_plugin = plugin;
} }
@ -354,9 +352,21 @@ void Manager::InitPreScript()
for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin(); for ( plugin_list::iterator i = Manager::ActivePluginsInternal()->begin();
i != Manager::ActivePluginsInternal()->end(); i++ ) i != Manager::ActivePluginsInternal()->end(); i++ )
{ {
Plugin* plugin = *i; (*i)->DoConfigure();
plugin->DoConfigure(); }
plugin->InitPreScript();
// 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; 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 void Plugin::Describe(ODesc* d) const
{ {
d->Add(config.name); d->Add(config.name);

View file

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

View file

@ -13,7 +13,9 @@ class TaggedComponent {
public: 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 * @param subtype A subtype associated with this component that
* further distinguishes it. The subtype will be integrated into * further distinguishes it. The subtype will be integrated into
@ -23,6 +25,12 @@ public:
*/ */
TaggedComponent(typename T::subtype_t subtype = 0); 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. * @return The component's tag.
*/ */
@ -30,6 +38,8 @@ public:
private: private:
T tag; /**< The automatically assigned analyzer tag. */ 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 static typename T::type_t type_counter; /**< Used to generate globally
unique tags. */ unique tags. */
}; };
@ -37,12 +47,23 @@ private:
template <class T> template <class T>
TaggedComponent<T>::TaggedComponent(typename T::subtype_t subtype) 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); tag = T(++type_counter, subtype);
} }
template <class T> template <class T>
T TaggedComponent<T>::Tag() const T TaggedComponent<T>::Tag() const
{ {
assert( initialized );
return tag; return tag;
} }