mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
Extend plugin infrastructure to catch Bro version mismatches at link
time. People keep running into the problem that they upgrade Bro but forget to recompile their plugins--which can lead to crashes. While the plugins' API version was supposed to catch this, it's not reliable as that check may come too late. This change takes a different tack: We compile a C function into the Bro binary that has Bro's version number encoded into its name. A plugin can then reference that function. If the Bro version changes, the function goes away and the plugin won't load anymore. I've integrated that function reference into the plugin skeleton code so that new plugins get it automatically (unless explicitly removed). I couldn't see a way to do it transparently for already existing plugins unfortunately. The version number used for the function name is slightly normalized to skip any git revision postfixes (i.e., "2.5-xxx" is always treated as "2.5-git") so that one doesn't need to recompile all plugins after every master commit. That seems good enough, usually people run into this when upgrading to a new release. If one loads an old plugin into a new Bro, the error message looks like this: $ bro -NN Demo::Foo fatal error in /home/robin/bro/master/scripts/base/init-bare.bro, line 1: cannot load plugin library /home/robin/tmp/p/build//lib/Demo-Foo.linux-x86_64.so: /home/robin/tmp/p/build//lib/Demo-Foo.linux-x86_64.so: undefined symbol: bro_version_2_5_git_debug Not the prettiest, but better than a crash! TODO: I'm still unsure if we should remove the plugin API version altogetger now. This link-time check should catch everything the API version does, except for master commits.
This commit is contained in:
parent
ffa7480ce4
commit
8ae30d8aac
5 changed files with 42 additions and 1 deletions
|
@ -40,12 +40,21 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev.csh
|
||||||
"setenv PATH \"${CMAKE_CURRENT_BINARY_DIR}/src\":$PATH\n")
|
"setenv PATH \"${CMAKE_CURRENT_BINARY_DIR}/src\":$PATH\n")
|
||||||
|
|
||||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
|
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
|
||||||
|
|
||||||
string(REPLACE "." " " version_numbers ${VERSION})
|
string(REPLACE "." " " version_numbers ${VERSION})
|
||||||
separate_arguments(version_numbers)
|
separate_arguments(version_numbers)
|
||||||
list(GET version_numbers 0 VERSION_MAJOR)
|
list(GET version_numbers 0 VERSION_MAJOR)
|
||||||
list(GET version_numbers 1 VERSION_MINOR)
|
list(GET version_numbers 1 VERSION_MINOR)
|
||||||
set(VERSION_MAJ_MIN "${VERSION_MAJOR}.${VERSION_MINOR}")
|
set(VERSION_MAJ_MIN "${VERSION_MAJOR}.${VERSION_MINOR}")
|
||||||
|
|
||||||
|
set(VERSION_C_IDENT "${VERSION}")
|
||||||
|
string(REGEX REPLACE "-[0-9]*$" "_git" VERSION_C_IDENT "${VERSION_C_IDENT}")
|
||||||
|
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" VERSION_C_IDENT "${VERSION_C_IDENT}")
|
||||||
|
|
||||||
|
if(${ENABLE_DEBUG})
|
||||||
|
set(VERSION_C_IDENT "${VERSION_C_IDENT}_debug")
|
||||||
|
endif()
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
## Dependency Configuration
|
## Dependency Configuration
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 43f4b90bbaf87dae1a1073e7bf13301e58866011
|
Subproject commit 7a38763d7a687dc8974bf6fd212dc75ba4a4b23c
|
|
@ -229,3 +229,14 @@
|
||||||
#ifndef BRO_PLUGIN_INTERNAL_BUILD
|
#ifndef BRO_PLUGIN_INTERNAL_BUILD
|
||||||
#define BRO_PLUGIN_INTERNAL_BUILD @BRO_PLUGIN_INTERNAL_BUILD@
|
#define BRO_PLUGIN_INTERNAL_BUILD @BRO_PLUGIN_INTERNAL_BUILD@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* A C function that has the Bro version encoded into its name. */
|
||||||
|
#define BRO_VERSION_FUNCTION bro_version_@VERSION_C_IDENT@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
extern const char* BRO_VERSION_FUNCTION();
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#define BRO_PLUGIN_API_VERSION 5
|
#define BRO_PLUGIN_API_VERSION 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define BRO_PLUGIN_BRO_VERSION BRO_VERSION_FUNCTION
|
||||||
|
|
||||||
class ODesc;
|
class ODesc;
|
||||||
class Func;
|
class Func;
|
||||||
class Event;
|
class Event;
|
||||||
|
@ -93,6 +95,12 @@ public:
|
||||||
// strong hint.). The attribute seems generally available.
|
// strong hint.). The attribute seems generally available.
|
||||||
inline Configuration() __attribute__((always_inline));
|
inline Configuration() __attribute__((always_inline));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One can assign BRO_PLUGIN_BRO_VERSION to this to catch
|
||||||
|
* version mismatches at link(!) time.
|
||||||
|
*/
|
||||||
|
const char* (*bro_version)();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Plugin;
|
friend class Plugin;
|
||||||
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
|
int api_version; // Current BRO_PLUGIN_API_VERSION. Automatically set.
|
||||||
|
@ -103,6 +111,7 @@ inline Configuration::Configuration()
|
||||||
name = "";
|
name = "";
|
||||||
description = "";
|
description = "";
|
||||||
api_version = BRO_PLUGIN_API_VERSION;
|
api_version = BRO_PLUGIN_API_VERSION;
|
||||||
|
bro_version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1 +1,13 @@
|
||||||
|
|
||||||
|
#include "bro-config.h"
|
||||||
|
|
||||||
char version[] = "@VERSION@";
|
char version[] = "@VERSION@";
|
||||||
|
|
||||||
|
// A C function that has the current version built into its name.
|
||||||
|
// One can link a shared library against this to ensure that it won't
|
||||||
|
// load if the version of the main Bro binary differs compared to
|
||||||
|
// what the library was compiled against.
|
||||||
|
const char* BRO_VERSION_FUNCTION()
|
||||||
|
{
|
||||||
|
return "@VERSION_C_IDENT@";
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue