SCIM 1.4.8 で segfault を回避

SCIM を 1.4.8 にすると scim-helper-man で segfault が起きる。噂によると KDE が起動しない場合もあるらしい。

Feb 25 23:10:14 localhost kernel: scim-helper-man[30663]: segfault at 208 ip 001b33b9 sp bf8ae980 error 4 in libscim-1.0.so.8.2.4 (deleted [133000+ca000]

1.4.7 から 1.4.8 への変更を見比べてみると、どうも r114 で src/scim_helper_manager_server.cpp に加えた変更が怪しいようだ。確信はないが、この変更を元に戻す以下のパッチを当てると segfault を回避できるようになった。

Index: src/scim_helper_manager_server.cpp
===================================================================
--- src/scim_helper_manager_server.cpp	(revision 114)
+++ src/scim_helper_manager_server.cpp	(revision 113)
@@ -90,36 +90,29 @@
 
     scim_get_helper_module_list (mod_list);
 
-    // NOTE on FreeBSD if some module is loaded and unloaded right away here the following module crashes for some unknown reason
-    //      seems like some damage is being done by module.unload();
-    //      so I added a workaround: have an array of modules and unload them all together in the end only.
-    //      TODO Need to figure out what's going on with this issue.
-
-    HelperModule module[mod_list.size ()];
-
     if (mod_list.size ()) {
+        HelperModule module;
 
         for (size_t i = 0; i < mod_list.size (); ++i) {
 
             SCIM_DEBUG_MAIN (2) << " Load module: " << mod_list [i] << "\n";
 
-            if (module[i].load (mod_list [i]) && module[i].valid ()) {
+            if (module.load (mod_list [i]) && module.valid ()) {
                 HelperInfo info;
-                size_t num = module[i].number_of_helpers ();
+                size_t num = module.number_of_helpers ();
 
                 SCIM_DEBUG_MAIN (2) << " Find " << num << " Helpers:\n";
 
                 for (size_t j = 0; j < num; ++j) {
-                    if (module[i].get_helper_info (j, info)) {
+                    if (module.get_helper_info (j, info)) {
                         SCIM_DEBUG_MAIN (3) << "  " << info.uuid << ": " << info.name << "\n";
                         __helpers.push_back ( std::make_pair (info, mod_list [i]) );
                     }
                 }
             }
+
+            module.unload ();
         }
-        for (size_t i = 0; i < mod_list.size (); ++i) {
-            module[i].unload ();
-        }
     }
 }