jlessのデバッグ
先日のja-lessでCRLFが^Mと表示される問題と、それに対するhiroさんからのコメントを受けてデバッグしてみました.以下,デバッグしながらのメモです.日本語がおかしかったり、ソースを見ながらでないとわからなかったりする部分がありますがご容赦を。
まず,gdb ~/bin/jless jless.core してみます.
Core was generated by `jless'. Program terminated with signal 6, Aborted. Reading symbols from /lib/libncurses.so.5...done. Loaded symbols for /lib/libncurses.so.5 Reading symbols from /lib/libc.so.5...done. Loaded symbols for /lib/libc.so.5 Reading symbols from /libexec/ld-elf.so.1...done. Loaded symbols for /libexec/ld-elf.so.1 #0 0x2811c1d7 in kill () from /lib/libc.so.5 (gdb)
ということで,わかる人にはわかるんだろうけど,何だコレはという感じです(泣).signal 6ってABRT (abort)ですか.
あと頼りになりそうなのはエラーメッセージです.「Assertion failed: (0), function convert_to_ujis, file multi.c, line 2157.」ということなので,multi.cの2157行目を見てみると
assert(0);
です.assertってのは引数が偽だった場合にabort()を呼ぶらしい.式が本当に真となることを確認するために使うということです.しかしassert(0)は真になり得ないので,「ここには来ないはず」ということを言いたいのでしょう.その上の部分を見ていくと,条件分岐がたくさんあります.if文の中身を省略すると
static char *convert_to_ujis(c, cs) { (snip) if (CSISWRONG(cs)){ cs = ASCII; } cs = CS2CHARSET(cs); if (cs == ASCII || cs == JISX0201ROMAN){ ... } else if (cs == JISX0201KANA) { ... } else if (cs == JISX0208_78KANJI || cs == JISX0208KANJI || cs == JISX0208_90KANJI || cs == JISX0213KANJI1) { ... } else if (cs == JISX0212KANJISUP) { ... } else if (cs == JISX0213KANJI2) { ... } assert(0);
csは上記のASCII〜JISX0213KANJI2のどれかのはずなのに,どれにも該当しなかったよ〜ってことですか.csという変数がどこから来たかを調べたいところですが,とりあえずprintfを仕込んで,エラーが発生するときに c と cs がどうなっているかを見てみます.表示させるフィルの中身は,EUCで「テストです」と書いてあります.すると,cはファイルによって不定で,csは289でした.289をビット列で表すと100100001.multi-byteで,94x94 graphic setsで,FT2CS('Q')に該当するので,JISX02132004KANJI1だということが判明しました.このCHARSETは上の条件分岐に含まれていませんので,テキトーにJISX0213KANJI1のあと辺りに追加してやると,めでたくエラーもなく文字化けもせず表示されるようになりました.
この部分だけ見ると条件分岐にJISX02132004KANJI1やJISX02132004KANJI2が含まれていないのが問題のようにも思えるのですが,それ以前のcsの判定の問題かも知れません.あと,258から260へのpatchのどの部分でおかしくなったかも突き止めたいところです.単純にJISX02132004KANJI1でgrepしたところ,
less-382-iso258-259.patch:+#define JISX02132004KANJI1 (TYPE_94N_CHARSET | FT2CS('Q'))
というのが見つかるので,259でこのCHARSETが新たに定義されているっぽい雰囲気です.さらに260で
less-382-iso259-260.patch:+ } else if (cs == JISX02132004KANJI1)
と言う処理も加わっていて,これを見るとmulti.cのconvert_to_jisという関数に
} else if (cs == JISX02132004KANJI1) { if (cvindex == 1) return (nullcvbuffer); assert(cvindex == 2); cvindex = 0; cs = JISX0208KANJI;
という処理が追加されています.同様にconvert_to_ujisでも処理を追加しないといけなかったのに,忘れていたということでしょうか?
はてさて,作者さんにメールするには何をどう書いたものですかね.自信があればpatchを送るで済むんでしょうが,これで正しいという自信がこれっぽっちもないので.