After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 565681 - EPlugin initialization
EPlugin initialization
Status: RESOLVED FIXED
Product: evolution
Classification: Applications
Component: Plugins
unspecified
Other Linux
: Urgent critical
: ---
Assigned To: Sankar P
Evolution QA team
Depends on:
Blocks: 565091
 
 
Reported: 2008-12-26 12:01 UTC by Philip Van Hoof
Modified: 2009-01-12 08:45 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
This seems to fix it for me (4.36 KB, patch)
2009-01-09 13:34 UTC, Philip Van Hoof
accepted-commit_now Details | Review

Description Philip Van Hoof 2008-12-26 12:01:15 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

Thread 3059599136 (LWP 29320)

  • #0 enable_plugin
    at tracker-evolution-plugin.c line 892
  • #1 e_plugin_lib_enable
    at tracker-evolution-plugin.c line 1029
  • #2 epl_loadmodule
    at e-plugin.c line 1005
  • #3 epl_get_configure_widget
    at e-plugin.c line 1100
  • #4 e_plugin_get_configure_widget
    at e-plugin.c line 841
  • #5 org_gnome_plugin_manager_manage
    at plugin-manager.c line 328
  • #6 epl_invoke
    at e-plugin.c line 1035
  • #7 e_plugin_invoke
    at e-plugin.c line 769
  • #8 emph_menu_activate
    at e-menu.c line 633
  • #9 em_activate
    at e-menu.c line 336
  • #10 ??
    from /usr/lib/libbonoboui-2.so.0
  • #11 g_closure_invoke
    from /usr/lib/libgobject-2.0.so.0
  • #12 bonobo_closure_invoke_va_list
    from /usr/lib/libbonobo-2.so.0
  • #13 bonobo_closure_invoke
    from /usr/lib/libbonobo-2.so.0
  • #14 ??
    from /usr/lib/libbonoboui-2.so.0
  • #15 _ORBIT_skel_small_Bonobo_UIComponent_execVerb
    from /usr/lib/libbonobo-2.so.0
  • #16 ORBit_c_stub_invoke
    from /usr/lib/libORBit-2.so.0
  • #17 Bonobo_UIComponent_execVerb
    from /usr/lib/libbonobo-2.so.0
  • #18 ??
    from /usr/lib/libbonoboui-2.so.0
  • #19 g_cclosure_marshal_VOID__POINTER
    from /usr/lib/libgobject-2.0.so.0
  • #20 ??
    from /usr/lib/libgobject-2.0.so.0
  • #21 g_closure_invoke
    from /usr/lib/libgobject-2.0.so.0
  • #22 ??
    from /usr/lib/libgobject-2.0.so.0
  • #23 g_signal_emit_valist
    from /usr/lib/libgobject-2.0.so.0
  • #24 g_signal_emit
    from /usr/lib/libgobject-2.0.so.0
  • #25 bonobo_ui_engine_emit_verb_on_w
    from /usr/lib/libbonoboui-2.so.0
  • #26 ??
    from /usr/lib/libbonoboui-2.so.0
  • #27 g_cclosure_marshal_VOID__VOID
    from /usr/lib/libgobject-2.0.so.0
  • #28 g_closure_invoke
    from /usr/lib/libgobject-2.0.so.0
  • #29 ??
    from /usr/lib/libgobject-2.0.so.0
  • #30 g_signal_emit_valist
    from /usr/lib/libgobject-2.0.so.0
  • #31 g_signal_emit
    from /usr/lib/libgobject-2.0.so.0
  • #32 gtk_widget_activate
    from /usr/lib/libgtk-x11-2.0.so.0
  • #33 gtk_menu_shell_activate_item
    from /usr/lib/libgtk-x11-2.0.so.0
  • #34 ??
    from /usr/lib/libgtk-x11-2.0.so.0
  • #35 ??
    from /usr/lib/libgtk-x11-2.0.so.0
  • #36 ??
    from /usr/lib/libgtk-x11-2.0.so.0
  • #37 ??
    from /usr/lib/libgobject-2.0.so.0
  • #38 g_closure_invoke
    from /usr/lib/libgobject-2.0.so.0
  • #39 ??
    from /usr/lib/libgobject-2.0.so.0
  • #40 g_signal_emit_valist
    from /usr/lib/libgobject-2.0.so.0
  • #41 g_signal_emit
    from /usr/lib/libgobject-2.0.so.0
  • #42 ??
    from /usr/lib/libgtk-x11-2.0.so.0
  • #43 gtk_propagate_event
    from /usr/lib/libgtk-x11-2.0.so.0
  • #44 gtk_main_do_event
    from /usr/lib/libgtk-x11-2.0.so.0
  • #45 ??
    from /usr/lib/libgdk-x11-2.0.so.0
  • #46 g_main_context_dispatch
    from /usr/lib/libglib-2.0.so.0
  • #47 ??
    from /usr/lib/libglib-2.0.so.0
  • #48 g_main_loop_run
    from /usr/lib/libglib-2.0.so.0
  • #49 bonobo_main
    from /usr/lib/libbonobo-2.so.0
  • #50 main
    at main.c line 694

Comment 1 Matthew Barnes 2008-12-26 18:47:37 UTC
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.
Comment 2 Philip Van Hoof 2008-12-26 18:54:51 UTC
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.
Comment 3 Srinivasa Ragavan 2009-01-04 19:15:31 UTC
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]
Comment 4 Philip Van Hoof 2009-01-09 11:24:22 UTC
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
Comment 5 Philip Van Hoof 2009-01-09 11:27:31 UTC
(gdb) bt

Thread 3059603232 (LWP 27042)

  • #0 mail_session_init
    at mail-session.c line 698
  • #1 mail_component_init
    at mail-component.c line 1300
  • #2 g_type_create_instance
    from /usr/lib/libgobject-2.0.so.0
  • #3 ??
    from /usr/lib/libgobject-2.0.so.0
  • #4 ??
    from /usr/lib/libbonobo-2.so.0
  • #5 g_object_newv
    from /usr/lib/libgobject-2.0.so.0
  • #6 g_object_new_valist
    from /usr/lib/libgobject-2.0.so.0
  • #7 g_object_new
    from /usr/lib/libgobject-2.0.so.0
  • #8 mail_component_peek
    at mail-component.c line 1324
  • #9 em_format_html_get_type
    at em-format-html.c line 266
  • #10 make_factory
    at mail-component-factory.c line 101
  • #11 bonobo_activation_activate_shlib_server
    from /usr/lib/libbonobo-activation.so.4
  • #12 ??
    from /usr/lib/libbonobo-activation.so.4
  • #13 bonobo_activation_activate
    from /usr/lib/libbonobo-activation.so.4
  • #14 bonobo_activation_activate_from_id
    from /usr/lib/libbonobo-activation.so.4
  • #15 query_components
    at e-component-registry.c line 175
  • #16 e_component_registry_peek_list
    at e-component-registry.c line 270
  • #17 e_shell_construct
    at e-shell.c line 695
  • #18 e_shell_new
    at e-shell.c line 745
  • #19 idle_cb
    at main.c line 337
  • #20 ??
    from /usr/lib/libglib-2.0.so.0
  • #21 g_main_context_dispatch
    from /usr/lib/libglib-2.0.so.0
  • #22 ??
    from /usr/lib/libglib-2.0.so.0
  • #23 g_main_loop_run
    from /usr/lib/libglib-2.0.so.0
  • #24 bonobo_main
    from /usr/lib/libbonobo-2.so.0
  • #25 main
    at main.c line 695

Comment 6 Philip Van Hoof 2009-01-09 11:29:22 UTC
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.
Comment 7 Matthew Barnes 2009-01-09 12:49:35 UTC
Don't know if this is possible with Bonobo, but maybe your plugin could extract 'session' from the mail component on demand via dlsym()?
Comment 8 Philip Van Hoof 2009-01-09 13:34:15 UTC
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
Comment 9 Matthew Barnes 2009-01-09 14:07:04 UTC
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.
Comment 10 Philip Van Hoof 2009-01-09 14:15:23 UTC
Will do, will also wait for Sankar's opinion.

Assigning to Sankar for review.
Comment 11 Sankar P 2009-01-12 08:37:06 UTC
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. 
Comment 12 Philip Van Hoof 2009-01-12 08:45:48 UTC
Committed as rev 37052 on Evolution's trunk