[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freewnn:00916] Re: dtoa SEGV
2002年09月07日(土)の05時01分に 亀井 信義 曰く:
> なんですが、 -R で作成した自分の辞書に、幾つか単語登録をしたところで、
> dtoa をやると、やはり SEGV (笑)。
>
> 実は、こっちが元々の問題でした。
> この壊れた辞書(と思う)は、jserverで読み込むことができません。
> サーバがコケて死にます。
>
> こっちについては継続調査です(なので、自動的に青野さんの今回の atod パッチも保留になってしまうと思うのです)。
>
>
再発したので、もう少し追いかけてみました。
サーバ側処理迄は見てない(これはマニュアルには載ってるようですが)、
ちょっと辛いので、誰か助けて欲しいです。
再現状況は、以下の通り。
1. 正常に使用できている辞書がある(確認したのは、逆変換可能辞書)
2. タイミングは不明だが、その辞書に対して複数の単語登録を行なうと、
どこかの時点で辞書が壊れる。
3. 但し、辞書がメモリ上のままならば、問題なく追加登録した単語を含めて使える。
4. Emacs上でのwnn-closeなどで、辞書をファイルに書き戻すと、壊れる。
5. 壊れた辞書は、jserverをクラッシュすることがある。
6. 壊れた辞書は、dtoaでダンプしようとすると、dtoaがSEGVする。
7. 壊れた辞書ファイルの漢字や読みの部分は、一見きちんと格納されている
(ヘキサダンプして、EUC漢字コードと対応づけると、正しい)
dtoaをgdbで追っかけると、
* 正しい辞書の場合 rdtoujis に入った直後の時点、
正確には、main()中で revdic() が完了した時点で、
(gdb) print/x *jt.ri2
$173 = {next = {0xffffffff, 0xffffffff}, kanjipter = 0x0}
となっている。
* 壊れた辞書の場合、同じ時点で、例えば
(gdb) print/x *jt.ri2
$175 = {next = {0x5f7fffff, 0xff1b2842}, kanjipter = 0x4d}
このようになっている。
rdtoujis() の後続の処理で、
jt.kanji[jt.ri2->kanjipter]
という場所から w_char 配列で、
0 ステート
1〜 読み
n〜 漢字
という形でのメモリ参照を行なうことになるので、
rdtoujis() の2重 for ループにおいて、「最初の jt.ri2->kanjipter は必ず
0」という仮定がもしあるとすれば、ここが 非0 なるが故のメモリ参照エラーとなる。
※ コード中に適度に assert があるべきだと思う。
辞書のフォーマットが、分からないんですよねぇ。
特にマッピングというかファイル内オフセットと内容。
なんとか、下記程度には理解しましたが。
メモ
逆引き可能辞書(shyurui == WNN_REV_DICT)での構造体 JT メンバの意味
ri1[D_YOMI] 読みの表
ri1[D_KANJI] 漢字の表
maxri1[D_YOMI] 読みの個数
maxri1[D_KANJI] 漢字の個数
kanji 漢字格納領域(w_char配列と見るべき)
kanji[0] ???
kanji[1] state; bit0 読み有り
bit1 漢字有り
bit2 コメント有り
kanji[2]〜kanji[m-1] 読み文字列
kanji[m] 0x00
kanji[m+1] 0x00
kanji[m+2]〜kanji[n-1] 漢字文字列
kanji[n] 0x00
kanji[n+1] 0x00
ri2 辞書内エントリの表
maxri2 辞書内エントリ数
maxserial 同上
dtoa.c:rdtoujis() では、
読み索引の順に、
同じ読みの漢字の順に、
get_kanji_str()で、漢字、読み、コメントを得る。
この段階では、各3変数の中身は big endian である。
--
亀井 信義