Bug #17184 init function of plugin so is not called
Submitted: 7 Feb 2006 10:01 Modified: 11 Feb 2009 13:16
Reporter: Sergei Golubchik Email Updates:
Status: Won't fix Impact on me:
None 
Category:MySQL Server: User-defined functions ( UDF ) Severity:S3 (Non-critical)
Version:5.1 OS:Any
Assigned to: CPU Architecture:Any

[7 Feb 2006 10:01] Sergei Golubchik
Description:
On certain architectures (mine is gcc 2.95.4, FreeBSD 5.4)
_mysql_plugin_declarations_ array, though it's initialized statically in the source, is not initialized statically in the resulting shared library - it's initialized dynamically from the __static_initialization_and_destruction_0 function.

MySQL does not call it, as a result _mysql_plugin_declarations_ is all zeros. Other global symbols that are POD types are initialized statically, though I'm not sure anymore we can rely on that.

How to repeat:
build ha_example plugin with gcc 2.95.3

Suggested fix:
1. find out whether such a behaviour of gcc is allowed
2. if yes - find  the standard name of .so init function and
3) load plugins as in:
  i) check for existance of well-known-symbols (but not their values)
     - reject so if they are not found
  ii) call .so init function
  iii) check for values of well-known-symbols
[17 Feb 2006 11:44] Sergey Vojtovich
As discussed on irc, bug status is to be fixed later.

C++ provides ability to use non-constant variables when initializing global
structures. However it is different from initialization when all elements are
set using constant variables. These variables are initialized in
__static_initialization_and_destruction_0 function, but this function is not
called when dlopen-ing shared library.

This doesn't affect plugins written in pure C, since pure C doesn't provide this
feature.

Since we're not going to change our plugin API, it seems there is no portable
way to call static variables initialization function.

Instead this must be documented in plugin API section.

Examples:
typedef struct
{
  int version;
  const char *name;
  ...
} handlerton;

handlerton example_hton= {
  MYSQL_HANDLERTON_INTERFACE_VERSION,
  "EXAMPLE",
  ...
};
----------
mysql_declare_plugin
{
  MYSQL_STORAGE_ENGINE_PLUGIN,
  &example_hton,
  example_hton.name, /* Wrong: example_hton.name is not const. */
  "Brian Aker, MySQL AB",
  "Example Storage Engine",
  example_init_func, /* Plugin Init */
  example_done_func, /* Plugin Deinit */
  0x0001 /* 0.1 */,
}
mysql_declare_plugin_end;
----------
mysql_declare_plugin
{
  MYSQL_STORAGE_ENGINE_PLUGIN,
  &example_hton,
  "EXAMPLE", /* Correct: "EXAMPLE" is const */
  "Brian Aker, MySQL AB",
  "Example Storage Engine",
  example_init_func, /* Plugin Init */
  example_done_func, /* Plugin Deinit */
  0x0001 /* 0.1 */,
}
mysql_declare_plugin_end;
----------
const char *example_handlerton_name= "EXAMPLE";
mysql_declare_plugin
{
  MYSQL_STORAGE_ENGINE_PLUGIN,
  &example_hton,
  example_handlerton_name, /* Correct: example_handlerton_name is const */
  "Brian Aker, MySQL AB",
  "Example Storage Engine",
  example_init_func, /* Plugin Init */
  example_done_func, /* Plugin Deinit */
  0x0001 /* 0.1 */,
}
mysql_declare_plugin_end;
[23 Feb 2006 13:09] Sergei Golubchik
Just for the record: the limitation is documented.

One of the particulary tempting places to use the invalid construct is loadable storage engines, because both handlerton and st_plugin store the engine's name.

We'll fix this by removing  'name' field from the handlerton.

But it's "To be fixed later"
[11 Feb 2009 13:16] Sergei Golubchik
No need to do even that - handlertons are now initialized dynamically, not statically, and the above is not an issue anymore.