[Freewnn-users 147] Re: make 'CCOPTIONS=-g' と指定するとatodがSEGVで落ちるようになる (was: Released 1.1.1-a022)

Back to archive index

ISHIKAWA,chiaki ishik****@yk*****
2013年 8月 21日 (水) 01:49:31 JST


入会したばかりの石川といいます。

ちょっとこころあたりがあるのでコメントします。

(2013/08/11 19:06), 1xx wrote:
> openSUSE 13.1 Milestone 3および4 x64 環境でbinary packageを作っていて、
> 奇妙な事に気付いたので報告しておきます。
> 
> 1. make 'CCOPTIONS=-g' と指定するとatodがSEGVで落ちるようになる。
> 
> 奇妙なことですが
> make
> と打ったときと
> make  'CCOPTIONS=-g'
> と打ったときでatodのfile sizeが異なります。
> 
>   'CCOPTIONS=-g'  あり:
>> ls -l atod
> -rwxr-xr-x 1 mitsutoshi users 217286 Aug 11 17:55 atod
> オプションなし:
>> ls -l ~/atod
> -rwxr-xr-x 1 mitsutoshi users 217183 Aug 11 15:55 /home/mitsutoshi/atod
> 
> make  'CCOPTIONS=-g'  と打った方はmakeの辞書の作成時にSEGVで落ちます。
> 
> GNU gdb (GDB; openSUSE Factory) 7.5.50.20130215
> Copyright (C) 2013 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-suse-linux".
> For bug reporting instructions, please see:
> <http://bugs.opensuse.org/>...
> Reading symbols from
> /home/mitsutoshi/src/FreeWnn-1.1.1-a022/Wnn/jutil/atod...done.
> [New LWP 20874]
> Core was generated by `../..//Wnn/jutil/atod -p Version -P Version -h
> ../..//Wnn/jd/hinsi.data bio.dic'.
> Program terminated with signal 11, Segmentation fault.
> #0  __strncpy_ssse3 () at ../sysdeps/x86_64/multiarch/strcpy-ssse3.S:43
> 43      ../sysdeps/x86_64/multiarch/strcpy-ssse3.S: No such file or directory.
> (gdb) bt full
> #0  __strncpy_ssse3 () at ../sysdeps/x86_64/multiarch/strcpy-ssse3.S:43
> No locals.
> #1  0x00000000004065da in strncpy (__len=16, __src=<optimized out>,
>      __dest=0x658428 <jt+8> "") at /usr/include/bits/string3.h:120
> No locals.
> #2  new_pwd (src=src @ entry=0x7fff33a4d760 "Pubdic+ Version",
>      encd=encd @ entry=0x658428 <jt+8> "") at ../..//Wnn/etc/pwd.c:93
>          i = 2
>          x = <optimized out>
>          c = <optimized out>
>          xx = "7j"
>          cr = <optimized out>
> #3  0x0000000000401a25 in get_pwd (fname=0x7fff33a4f1c5 "Version",
>      crypted=0x658428 <jt+8> "") at atod.c:807
>          pwd = "Pubdic+ Version"
>          fp = 0x106b010
> #4  0x0000000000401b01 in init (argc=8, argv=0x7fff33a4d8d8) at atod.c:147
>          c = <optimized out>
> #5  0x00000000004012b9 in main (argc=<optimized out>, argv=<optimized out>)
>      at atod.c:236
>          cswidth_name = <optimized out>
> (gdb) quit
> 
> 何故こうなるのかの解明には至っておりませんが、ご報告まで。
> 

上をみると strncpy のSSSE3 版を使っているところで落ちています。
SSSE3を使ったstring関係の関数は、SSE3の大量バイトまとめてコピー機能を使うために、
ソースのアドレスの値によっては、関係のないところまで読みにいきます。(さすがに書き込みは
しないはずですが)。

一見高速化の手法として問題ないかのようにみえますが、ひとつ落とし穴があります。
ソース領域が brk(), sbrk() で確保された有効なアドレスの直前にあるときに問題が起こりえます。
高速コピー機能を利用しようとしてSSSE3がよみにいった16だったか32バイト領域の終わりが
sbrk(),brk() でとった有効領域の外に出てしまうと当然ですがOSはsigsegv でプログラムを強制終了させます。

昔にたような特殊命令を使っているコンピュータで、プログラムが落ちて
長いデバッグの末、CPUが特殊命令の中でmap済みの有効空間の外にアクセスしている(その場合には
コピーの際に 4バイトだったか8バイト単位でおこなっていて、後半が有効ページからはみ出ていた
ことがありました。プログラムはsigsegv相当で落ちており、しかしポインタが特殊命令を指しており、
命令パラメータは問題なさそうなのですぐに原因に気づきませんでした。実行中にCPUが余計なバイトまで
アクセスしているとは知りませんでした。そのあとコピー開始位置、長さを、sbr(0)付近で
使える有効なアドレスにして、いろいろずらして試してみて原因を特定しました。たぶんCPUの
マイクロプログラムを書いた人と話ができればすぐに解決したのでしょうが。)

果たして、上の推論が正しいかどうかはgdb をかませて実行して、おちそうなときの
strncpyのソースアドレスの値と、
そのときの有効なデータ空間の最後(むむむ、どうやって得るのかな?自分で sbrk(0)をして
その値のダンプするのか?)
を比較することで判断できそうです。

ちなみに、長年親しんだDebian  32bit から 64 bitに移行したところ
jserver <-> emacs tamago/egg の動作はOK.
firefox/thunderbirdで kinpu2-wnnがまったく日本語入力できず(シフトスペースで
入力モードが変更されない)、
自分で作ったkinput2 を使うと動作することを確認できたのですが、
一回か2回変換をすると 今度は jserver がクラッシュしてしまいます。
自分で a022をコンパイルしたところ多数の警告がでて、
どうもプロトタイプのミスマッチなどが予想されたので、
公開していただいたopensuseのパッチをもとにDebian でもテストしてみます。

その際に上のstrncp SSSE3に起因すると思われる問題動作もこちらの
環境で再現するか確認してみます。

石川




freewnn-users メーリングリストの案内
Back to archive index