Not only is the Internet dead, it's starting to smell really bad.:2009年02月08日分

2009/02/08(Sun)

[NetBSD] pkgsrc/wip/scim

SuSE Linux 11.1がscim標準だったはずなのでインスコしてみた。
なぜかscim標準のgtkimmoduleでなしに scim-bridgeを使ってる、なんぞ?

ちゅうかscim-bridgeのプロジェクトページに

You can use this to avoid the problem caused by C++ ABI transition.

とか書いてありやがんの、あsdfghjkl
まぁ今回の件は同じverのgcc/g++だから違うんだけど、やっぱりC++以下略

まぁでも、SuSEだとGTK_IM_MODULE=scimで起動してもクラッシュしないのだね。
ちょっとこの環境で調べてみますか。

とりあえずNetBSDの場合にはstatic objectのdestructorで氏にまくりなので
こんな patchでMemory Fault発生しないようにした。
class ConfigPointerがなぜ明示的に初期化せんと落ちるのかはよく判らんけど
FinalizeHandlerはGTK2のim_module_exit()イベントですでに終了処理は終わってるので
冗長な処理だし不要だと思われ、まぁC++だとdestructorで終了処理するのが定石みたいだけど。

あとは__deregister_frame_info()問題とg++のchar_traits最適化問題かぁ。
もうC++爆発しろ!

今日

current-users、本場物の " In Soviet Russia" ワロタ。

[NetBSD] __deregister_frame_info

まずはC++で書かれたshlibとC以下同文をdlopen(3)する簡単なサンプルを書いてテスト。

$ cat >foo.h
#if defined(__cplusplus)
extern "C" {
#endif
void foo(void);
#if defined(__cplusplus)
}
#endif
^D
$ cat >foo.cpp
#include <string>
#include <iostream>
#include "foo.h"

void
foo(void)
{
        std::basic_string<char> msg;
        msg = std::basic_string<char>("hello, C++ world.\n");
        std::cout << msg;
}
^D
$ g++ -shared -g -o libfoo.so foo.cpp
$ cat >bar.h
void bar(void);
^D
$ cat >bar.c
#include <stdio.h>
#include "bar.h"

void
bar(void)
{
        printf("hello, C world.\n");
}
^D
$ gcc -shared -g -o libbar.so bar.c

結果、Trying to call undefined weak symbol `__deregister_frame_info'が発生するのは
dlopen(RTLD_GLOBAL)でloadした場合かつ、C++なshlibをdlclose(3)してからC以下同文のみ。

$ cat >buzz.c
#include <dlfcn.h>

typedef void (*func_t)(void);
int
main(void)
{
        void *foo, *foo_func, *bar, *bar_func;
        foo = dlopen("/home/tnozaki/libfoo.so", RTLD_GLOBAL);
        foo_func = dlsym(foo, "foo");
        ((func_t)foo_func)();
        bar = dlopen("/home/tnozaki/libbar.so", RTLD_GLOBAL);
        bar_func = dlsym(bar, "bar");
        ((func_t)bar_func)();
        dlclose(foo);
        dlclose(bar);
        return 0;
^D
$ gcc -g -o buzz buzz.c
$ ./buzz
hello, C++ world.
hello, C world.
/home/tnozaki/libbar.so: Trying to call undefined weak symbol `__deregister_frame_info'

じゃ単純にRTLD_LAZYあたりに書き換えりゃいいかってーとそうでもなくて
Solarisの ドキュメントにはRTLD_GLOBALを使わないと例外も使えないともある、うーみゅ。