[Freewnn-users 71] freewnn-jserver が辞書登録で落ちる場合がある

Hideki Yamane henri****@debia*****
2010年 12月 4日 (土) 11:14:46 JST


 やまねです。

 twitter で教えていただいたのですが、Debian squeeze 以降の freewnn-jserver
 で emacs から辞書登録を行うと jserver が落ちる現象が出る場合があるようです。
 原因と思われる部分についてパッチを頂きました。ご意見頂けますか?

$ diff -u freewnn-1.1.1~a021+cvs20100325/Wnn/jserver/de_header.h{.original,}
--- freewnn-1.1.1~a021+cvs20100325/Wnn/jserver/de_header.h.original     2004-12-30 02:45:32.000000000 +0900
+++ freewnn-1.1.1~a021+cvs20100325/Wnn/jserver/de_header.h      2010-11-28 22:16:36.000000000 +0900
@@ -548,7 +548,7 @@
 extern void Get_knj2 ();
 extern void get_kanji_str ();
 extern void Get_kanji_str_r ();
-extern unsigned char *kanjiaddr ();
+extern unsigned char kanjiaddr ();
 extern int create_null_dic ();
 extern int create_hindo_file ();
 extern int input_header_jt ();

 

 問題の調査については以下のように詳細に確認頂いています。

> ソースのあちこちに prinf を入れて、変数の値を確かめたところ、
> struct JT の maxkanjiの値が、本来は int のはずなのに、
> どうもポインタが入っているような印象を受けました。
> 
> 特に怪しかったのが、Wnn/jserver/jishoop.c の関数 kanjiadd の最後の
> 
>   len = (int) kanjiaddr (dest, kanji, yomi, comment);
>   jtl->maxkanji += len;
> 
> という部分でしたので、この前後に printf を入れました。
> 
>    len = (int) kanjiaddr (dest, kanji, yomi, comment);
> +  fprintf(stderr, "in kanjiadd: before setting jtl->maxkanji; =%d, len=%d\n", jtl->maxkanji, len);
>    jtl->maxkanji += len;
> +  fprintf(stderr, "in kanjiadd: after setting jtl->maxkanji; =%d, len=%d\n", jtl->maxkanji, len);
> 
> すると、jserver が落ちた時に
> 
> Nov/28/2010:19:06:26 client=kasai: JS_WORD_ADD(49): cur_clp = 0
> in kanjiadd: before setting jtl->maxkanji; =770852, len=-1220287724
> in kanjiadd: after setting jtl->maxkanji; =-1219516872, len=-1220287724
> Nov/28/2010:19:06:28 client=kasai: JS_KANREN(17): cur_clp = 0
> 
> のように、len がありえない値になっていました。
> 一方、きちんと登録できたときのログは次のような感じです。
> 
> Nov/28/2010:19:09:46 client=kasai: JS_WORD_ADD(49): cur_clp = 0
> in kanjiadd: before setting jtl->maxkanji; =770852, len=20
> in kanjiadd: after setting jtl->maxkanji; =770872, len=20
> Nov/28/2010:19:09:48 client=kasai: JS_KANREN(17): cur_clp = 0
> 
> そこで、len の値を決めている kanjiaddr が定義されている Wnn/etc/bdic.c を見たところ、
> 
> UCHAR
> kanjiaddr (UCHAR* d0, w_char* kanji, w_char* yomi, w_char* comment)
> {
> (...)
>   *d0 = (UCHAR) ((UCHAR *) dest - d0);
>   *(d0 + 1) = state;
>   return (*d0);
> }
> 
> となっていました。ここでは、返り値は確かに UCHAR です。
> しかし、jishoop.c でインクルードしている Wnn/jserver/de_header.h では、
> 
> extern unsigned char *kanjiaddr ();
> 
> となっているために、
> 
>    len = (int) kanjiaddr (dest, kanji, yomi, comment);
> 
> の部分が、コードで意図した「UCHAR を int にキャストする」ことにならずに、
> ポインタを int にキャストする結果になっています。
> 
> 実際、アセンブラ出力を見ると、冒頭のパッチを当てる前と後で、
> kanjiaddr の戻り値の扱いが異なっていることがわかります。
> 
>  .LVL24:
>         movl    %eax, 4(%esp)
>         leal    (%ecx,%edx), %eax
>         movl    %eax, (%esp)
>         call    kanjiaddr
> -       movl    %eax, %esi
> -       .loc 1 426 0
> -       movl    %eax, 12(%esp)
> +       .loc 1 427 0
> +       movzbl  %al, %esi
> +.LVL25:
> +       .loc 1 428 0
> +       movl    %esi, 12(%esp)
>         movl    48(%ebx), %eax
>         movl    $.LC2, 4(%esp)
>         movl    %eax, 8(%esp)
>         movl    stderr, %eax
>         movl    %eax, (%esp)
>         call    fprintf




freewnn-users メーリングリストの案内