GNOME Bugzilla – Bug 565681
EPlugin initialization
Last modified: 2009-01-12 08:45:48 UTC
EPlugins are not being initialized until you do the Edit->Plugins menu. By not being initialized I mean that e_plugin_lib_enable is not being called. Please try before not believing me ;-) Note that the function *is* actually happening for two or three plugins, but not for all plugins. pls. Follow the traces and analysis ... This function is the one that executes it for those three: static Bonobo_Unknown make_factory (PortableServer_POA poa, const char *iid, gpointer impl_ptr, CORBA_Environment *ev) { static int init = 0; if (!init) { EImportClass *klass; init = 1; mail_config_init(); mail_msg_init(); e_plugin_hook_register_type(em_popup_hook_get_type()); e_plugin_hook_register_type(em_menu_hook_get_type()); e_plugin_hook_register_type(em_config_hook_get_type()); em_format_hook_register_type(em_format_get_type()); em_format_hook_register_type(em_format_html_get_type()); em_format_hook_register_type(em_format_html_display_get_type()); em_junk_hook_register_type(emj_get_type()); e_plugin_hook_register_type(em_format_hook_get_type()); e_plugin_hook_register_type(em_event_hook_get_type()); e_plugin_hook_register_type(em_junk_hook_get_type()); klass = g_type_class_ref(e_import_get_type()); e_import_class_add_importer(klass, mbox_importer_peek(), NULL, NULL); e_import_class_add_importer(klass, elm_importer_peek(), NULL, NULL); e_import_class_add_importer(klass, pine_importer_peek(), NULL, NULL); } return bonobo_shlib_factory_std (FACTORY_ID, poa, impl_ptr, factory, NULL, ev); } But it only happens for those (in my case two), as seen here: Program received signal SIGINT, Interrupt. [Switching to Thread 0xb65d1720 (LWP 28679)] 0xb7f2b410 in __kernel_vsyscall () (gdb) break epl_enable Breakpoint 1 at 0xb7e9b80d: file e-plugin.c, line 1115. (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /opt/evolution/bin/evolution [Thread debugging using libthread_db enabled] [New Thread 0xb667b720 (LWP 28765)] evolution-shell-Message: Killing old version of evolution-data-server... [Switching to Thread 0xb667b720 (LWP 28765)] Breakpoint 1, epl_enable (ep=0x808ef18, state=1) at e-plugin.c:1115 1115 EPluginLib *epl = E_PLUGIN_LIB (ep); (gdb) print *epl Cannot access memory at address 0x0 (gdb) next 1118 E_PLUGIN_CLASS (epl_parent_class)->enable (ep, state); (gdb) print *epl $1 = {plugin = {object = {g_type_instance = {g_class = 0x80cb060}, ref_count = 1, qdata = 0x0}, id = 0x80efe40 "org.gnome.evolution.plugin.preferPlain", path = 0x80e10e8 "/opt/evolution/lib/evolution/2.26/plugins/org-gnome-prefer-plain.eplug", hooks_pending = 0x80e86d8, description = 0x80ef840 "A test plugin which demonstrates a formatter plugin which lets you choose to disable HTML messages.\n\nThis plugin is unsupported demonstration code only.\n", name = 0x80f3108 "Prefer plain-text", domain = 0x0, hooks = 0x8111e18, authors = 0x80e86b8, flags = 0, enabled = 1}, location = 0x80ef790 "/opt/evolution/lib/evolution/2.26/plugins/liborg-gnome-prefer-plain.so", module = 0x0} (gdb) cont Continuing. Breakpoint 1, epl_enable (ep=0x808ec58, state=1) at e-plugin.c:1115 1115 EPluginLib *epl = E_PLUGIN_LIB (ep); (gdb) next 1118 E_PLUGIN_CLASS (epl_parent_class)->enable (ep, state); (gdb) print *epl $2 = {plugin = {object = {g_type_instance = {g_class = 0x80cb060}, ref_count = 1, qdata = 0x0}, id = 0x80e3590 "org.gnome.evolution.plugin.audioInline", path = 0x80e34b0 "/opt/evolution/lib/evolution/2.26/plugins/org-gnome-audio-inline.eplug", hooks_pending = 0x80d40d8, description = 0x80e2e90 "A formatter plugin which displays audio attachments inline and allows you to play them directly from Evolution.", name = 0x80d2e78 "Audio inline plugin", domain = 0x0, hooks = 0x0, authors = 0x80d40c8, flags = 0, enabled = 1}, location = 0x80e3518 "/opt/evolution/lib/evolution/2.26/plugins/liborg-gnome-audio-inline.so", module = 0x0} (gdb) cont Continuing. ** (evolution:28765): DEBUG: mailto URL command: evolution %s ** (evolution:28765): DEBUG: mailto URL program: evolution [New Thread 0xb6099b90 (LWP 28800)] [Thread 0xb6099b90 (LWP 28800) exited] (evolution:28765): Gtk-CRITICAL **: gtk_icon_info_free: assertion `icon_info != NULL' failed [New Thread 0xb6099b90 (LWP 28801)] [Thread 0xb6099b90 (LWP 28801) exited] [New Thread 0xb57ceb90 (LWP 28802)] [Thread 0xb57ceb90 (LWP 28802) exited] [New Thread 0xb57ceb90 (LWP 28803)] [New Thread 0xb6099b90 (LWP 28804)] [New Thread 0xb4fa6b90 (LWP 28805)] [New Thread 0xb47a5b90 (LWP 28806)] [New Thread 0xb3fa4b90 (LWP 28807)] [Thread 0xb3fa4b90 (LWP 28807) exited] [New Thread 0xb3fa4b90 (LWP 28808)] [Thread 0xb57ceb90 (LWP 28803) exited] [New Thread 0xb57ceb90 (LWP 28830)] [New Thread 0xb309fb90 (LWP 28831)] [Thread 0xb309fb90 (LWP 28831) exited] [Thread 0xb47a5b90 (LWP 28806) exited] [Thread 0xb6099b90 (LWP 28804) exited] [Thread 0xb4fa6b90 (LWP 28805) exited] [Thread 0xb3fa4b90 (LWP 28808) exited] [Thread 0xb57ceb90 (LWP 28830) exited] Or basically, there doesn't seem to be anything that performs the epl_enable for any of the dynamic EPlugins (the plugins that are not fixed-registered in Evolution, the ones that are only known to Evolution because they are .so files in the plugins-directory) ... *UNTIL* you do Edit->Plugins (and then epl_get_configure_widget is the one that makes it call on all plugins in the list being rendered for the UI): Program received signal SIGINT, Interrupt. 0xb7f53410 in __kernel_vsyscall () (gdb) break e_plugin_lib_enable Breakpoint 2 at 0xb7dc8a86: file caldav-source.c, line 102. (gdb) break enable_plugni Function "enable_plugni" not defined. Make breakpoint pending on future shared library load? (y or [n]) ^[[An Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) break enable_plugin Breakpoint 3 at 0xb3d401a1: file tracker-evolution-plugin.c, line 892. (gdb) delete `1 warning: bad breakpoint number at or near '`1' (gdb) delete 1 (gdb) delete 2 (gdb) cont Continuing. [Thread 0xb4615b90 (LWP 29288) exited] Program received signal SIGINT, Interrupt. 0xb7f53410 in __kernel_vsyscall () (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /opt/evolution/bin/evolution [Thread debugging using libthread_db enabled] [New Thread 0xb65dc720 (LWP 29320)] evolution-shell-Message: Killing old version of evolution-data-server... ** (evolution:29320): DEBUG: mailto URL command: evolution %s ** (evolution:29320): DEBUG: mailto URL program: evolution [New Thread 0xb5ffab90 (LWP 29344)] [Thread 0xb5ffab90 (LWP 29344) exited] (evolution:29320): Gtk-CRITICAL **: gtk_icon_info_free: assertion `icon_info != NULL' failed [New Thread 0xb5ffab90 (LWP 29345)] [Thread 0xb5ffab90 (LWP 29345) exited] [New Thread 0xb572fb90 (LWP 29346)] [Thread 0xb572fb90 (LWP 29346) exited] [New Thread 0xb572fb90 (LWP 29347)] [New Thread 0xb5ffab90 (LWP 29348)] [New Thread 0xb4dffb90 (LWP 29349)] [Thread 0xb4dffb90 (LWP 29349) exited] [New Thread 0xb4dffb90 (LWP 29351)] [New Thread 0xb431db90 (LWP 29352)] [New Thread 0xb3872b90 (LWP 29367)] [Thread 0xb4dffb90 (LWP 29351) exited] [New Thread 0xb4dffb90 (LWP 29368)] [Thread 0xb4dffb90 (LWP 29368) exited] [Thread 0xb572fb90 (LWP 29347) exited] [Thread 0xb5ffab90 (LWP 29348) exited] [Thread 0xb431db90 (LWP 29352) exited] [Thread 0xb3872b90 (LWP 29367) exited] [New Thread 0xb3872b90 (LWP 29374)] [New Thread 0xb431db90 (LWP 29375)] [Thread 0xb431db90 (LWP 29375) exited] [New Thread 0xb431db90 (LWP 29378)] (evolution:29320): Gtk-CRITICAL **: gtk_tree_view_column_set_resizable: assertion `GTK_IS_TREE_VIEW_COLUMN (tree_column)' failed (evolution:29320): Gtk-CRITICAL **: gtk_tree_view_column_set_reorderable: assertion `GTK_IS_TREE_VIEW_COLUMN (tree_column)' failed (evolution:29320): GLib-GObject-CRITICAL **: g_object_set: assertion `G_IS_OBJECT (object)' failed ** (evolution:29320): WARNING **: e_plugin_lib_enable
+ Trace 211078
Thread 3059599136 (LWP 29320)
Try putting a load-on-startup="true" attribute in your <e-plugin> tag. I can't defend what the point of that is, though. If we're not going let a plugin initialize itself on startup, then when? Initializing when the user brings up the list of plugins to check why it's not working is too late. What's happening now is EPlugins are constructed gradually as EPlugin and EPluginHook subclasses are registered. When an EPlugin collects all the hook instances it needs, it's ready to go. But we don't do anything to notify the subclasses (e.g. EPluginLib) when it's ready to go. Furthermore, EPlugins enable themselves immediately on creation by bypassing the enable() method (which would have triggered epl_loadmodule()) and just setting their own enabled flags directly. What I'd like to see happen is after the plugin is constructed and has all the hook instances it needs, only THEN does it enable itself (properly, using the enable() method). Then EPluginLib could load its GModule knowing the plugin is fully loaded and ready to go. That seems more straight-forward than what we're doing now. The current plugin loading semantics are pretty convoluted (I just spent two hours re-learning it again) and simplifying it to what I'm proposing would take some doing to sort out all the got'chas and corner cases.
ps. First test with this attribute added didn't seem to fix this. Will try again on Monday and search/read some more EPlugin-loading code.
Hmm, Lemme debug this. Just back from my official leave, hella lot of things to do. [Disk summary bugs are lot to fix, and then this. I promise to look at this, later this week]
pvanhoof session = something happens in mail_session_init pvanhoof Which is called by mail_component_init pvanhoof With load-on-startup="true" in your <e-plugin> epl_loadmodule happens in epl_construct pvanhoof (gdb) bt pvanhoof #0 epl_loadmodule (ep=0x808e8d0) at e-plugin.c:1014 pvanhoof #1 0xb7f1fa18 in epl_construct (ep=0x808e8d0, root=0x80d1290) at e-plugin.c:1084 pvanhoof #2 0xb7f1fd6c in e_plugin_construct (ep=0x808e8d0, root=0x80d1290) at e-plugin.c:739 pvanhoof #3 0xb7f1fe6a in ep_load_plugin (root=0x80d1290, pdoc=0x80d0b58) at e-plugin.c:416 pvanhoof #4 0xb7f203f9 in e_plugin_load_plugins () at e-plugin.c:464 pvanhoof #5 0x0805d543 in main (argc=1, argv=0xbf973ee4) at main.c:676 pvanhoof (gdb) pvanhoof Like that pvanhoof main.c:676 is before mail_component_init is called by the process pvanhoof So session doesn't exist * hpj (~hpj@30.79-160-149.customer.lyse.net) has joined #evolution pvanhoof because of that pvanhoof (evolution:26263): e-utils-WARNING **: can't load plugin '/opt/evolution/lib/evolution/2.26/plugins/liborg-freedesktop-Tracker-evolution-plugin.so': /opt/evolution/lib/evolution/2.26/plugins/liborg-freedesktop-Tracker-evolution-plugin.so: undefined symbol: session pvanhoof And because of that pvanhoof if ((epl->module = g_module_open(epl->location, 0)) == NULL) { pvanhoof g_warning("can't load plugin '%s': %s", epl->location, g_module_error()); pvanhoof return -1; pvanhoof } pvanhoof if (g_module_symbol(epl->module, "e_plugin_lib_enable", (void *)&enable)) { pvanhoof if (enable(epl, TRUE) != 0) { pvanhoof ... pvanhoof } pvanhoof So we get return -1 pvanhoof It never tries to e_plugin_lib_enable, it just ignores the module for now pvanhoof next time anything of the module is tried , it will find session pvanhoof so it will g_module_open it
(gdb) bt
+ Trace 211417
Thread 3059603232 (LWP 27042)
So, basically, plugins should not be attempted to become enabled until bonobo_main has ran once. As it's a bonobo component that will create the global variable sessions, and as a few EPlugins depend on that variable.
Don't know if this is possible with Bonobo, but maybe your plugin could extract 'session' from the mail component on demand via dlsym()?
Created attachment 126107 [details] [review] This seems to fix it for me I'm basically doing a second stage launch, and I avoid the plugin from loading if it has load-on-startup="after-ui" the first time. Please review
Adds to the complexity even more, but I suppose it's no worse than the kludges we're already pulling. Would you mind adding a comment to epl_loadmodule() explaining what's going on? Otherwise I guess it's okay. Sankar's the plugin guy though. Might run it by him before committing.
Will do, will also wait for Sankar's opinion. Assigning to Sankar for review.
I would recommend a GSList for missing_symbols. But I guess it is not a big deal as the number of plugins that are gonna depend on this is going to be small. As Matt suggested some comments on epl_loadmodule will be helpful for people in future. I have not tested the patch. But I believe you have verified and hence the Patch is approved for commit for both trunk and stable branch.
Committed as rev 37052 on Evolution's trunk