rrthomas / enchant

enchant spellchecking library
http://rrthomas.github.io/enchant/
GNU Lesser General Public License v2.1
347 stars 59 forks source link

Problem initializing aspell provider #385

Open ctrlaltca opened 5 months ago

ctrlaltca commented 5 months ago

Hello, we are using libenchant to provide spellchecking support in KVIrc. We recently received info about a crash related to a failure in initializing libenchant while using the aspell provider. Our code is calling new enchant::Broker(); to instantiate a new Broker and this leads to a crash with the following trace:

#0  g_log_structured_array (log_level=log_level@entry=G_LOG_LEVEL_ERROR, fields=fields@entry=0x7ffdd5dc9fd0, n_fields=4) at ../glib/glib/gmessages.c:426
#1  0x00007fc824719dd7 in g_log_default_handler
    (log_domain=log_domain@entry=0x7fc8245c4015 "GLib-GObject", log_level=log_level@entry=6, message=message@entry=0x56030e430be0 "cannot create new instance of invalid (non-instantiatable) type '<invalid>'", unused_data=unused_data@entry=0x0) at ../glib/glib/gmessages.c:3357
#2  0x00007fc82471a05c in g_logv
    (log_domain=0x7fc8245c4015 "GLib-GObject", log_level=G_LOG_LEVEL_ERROR, format=<optimized out>, args=args@entry=0x7ffdd5dca120)
    at ../glib/glib/gmessages.c:1246
#3  0x00007fc82471a3d4 in g_log
    (log_domain=log_domain@entry=0x7fc8245c4015 "GLib-GObject", log_level=log_level@entry=G_LOG_LEVEL_ERROR, format=format@entry=0x7fc8245cd018 "cannot create new instance of invalid (non-instantiatable) type '%s'") at ../glib/glib/gmessages.c:1315
#4  0x00007fc8245bf09b in g_type_create_instance (type=0x0) at ../glib/gobject/gtype.c:1881
#5  0x00007fc8080082da in enchant_provider_construct (object_type=<optimized out>) at /usr/src/debug/enchant/enchant-2.7.3/lib/provider.vala:85
#6  0x00007fc808008388 in enchant_provider_new () at /usr/src/debug/enchant/enchant-2.7.3/lib/provider.vala:85
#7  0x00007fc80806260e in init_enchant_provider () at /usr/src/debug/enchant/enchant-2.7.3/providers/enchant_aspell.c:198
#8  0x00007fc808008853 in enchant_broker_load_providers_in_dir (self=0x56030e056b00, dir_name=0x56030e4b31d0 "/usr/lib/enchant-2")
    at /usr/src/debug/enchant/enchant-2.7.3/lib/broker.vala:148
#9  enchant_broker_load_providers (self=0x56030e056b00) at /usr/src/debug/enchant/enchant-2.7.3/lib/broker.vala:121
#10 enchant_broker_init () at /usr/src/debug/enchant/enchant-2.7.3/lib/broker.vala:87
#11 0x00007fc80806a889 in ??? () at /usr/lib/kvirc/5.2/modules/libkvispellchecker.so

I tried to have a look at the code, but i'm not fluent in Vala/glib and was not able to figure out why g_type_create_instance is created with type=0x0.

rrthomas commented 5 months ago

I can't see how this can be a problem with the Enchant code per se, there's nothing going on here that isn't tested by the regular tests (in particular, creating an Aspell provider). I agree, it's a mystery how the type is set to 0; is it possible that the code is somehow mixing modules from different versions of Enchant? You don't have to worry about Vala, you can look at the generated C, which is fairly straightforward. In this case, setting type is entirely under the control of auto-generated C, and it looks like it's correct.

rrthomas commented 5 months ago

I tried building KVIrc from source and running it. It detected my Enchant, and I have Aspell installed and configured for English. In the languages preferences, I can see all my Enchant dictionaries listed as expected. I don't really understand how to make spell-checking work, so maybe I'm not triggering the crash: when I press Ctrl+G I get either a blank popup, a popup that says Spelling suggestions for 'foo', whether foo is a word, or not a word, or Spell Checker/No Suggestions Available.

rrthomas commented 5 months ago

I can now confirm I've managed to put breakpoints in the right place, and the Aspell back-end initialises fine (along with all the rest).

I am using Enchant 2.8.0, but there's no reason I can see why 2.7.3 should behave differently.

ctrlaltca commented 4 months ago

So, we had confirmation from the user that everything works fine in normal conditions. The spellchecker in KVIrc is implemented as an external module (.so/.dll) that can be loaded and unloaded from memory dynamically. The crash only happens after a load-unload-reload cycle, and is not reproducible all the times.

Honestly i'm not eager to debug why our memory management fails with GObjects, so by now we are adding a workaround forcing the spellchecker module to be never unloaded from memory. This should avoid the problematic condition.

Thank you for your help in trying to understand what was wrong here. Feel free to close the issue

rrthomas commented 4 months ago

Sounds like a failure in finalization then, either in KVIrc or in libenchant, though the manifestation is still weird.

I would suspect enchant_provider_get_type and its callee enchant_provider_get_type_once of failing to cope with this case of de- and re-initialization, specifically around the call to g_once_init_enter: I would suspect in particular that the call is really only initializing enchant_provider_type_id__once once, but that enchant_provider_type_id__once is being set back to 0 in between calls. It's not very likely as all of this code is entirely auto-generated, but it is at least possible (I've run into codegen bugs in the Vala compiler before).