mutt-1.2 (mutt-1.2.5.1i) | 2003-01-05 19:51 |
mutt-1.4 (mutt-1.4.2.1i-ja.1) | 2004-02-14 09:42 |
mutt-1.5 (mutt-1.5.23) | 2014-07-10 16:14 |
mutt-1.6 (mutt-1.6.1-ja.1) | 2016-08-22 17:11 |
mutt-ja (ja-mutt-1.11.4) | 2019-04-28 20:53 |
mutt-ja-package (FreeBSD9 pkg) | 2014-08-09 20:14 |
基本的に、別画面を出して、gdb から等外プロセスにattachすればよい。
ncursesにはトレース機能がついている。 通常では利用できない。トレース付きのライブラリを 別途インストールするようになっているが、それは static link用だったため、なぜかリンクエラーが出てしまった。 同じ名前のものがlibcにあるため、どちらを使うかで エラーが出ている様子。
コンパイル時にデバッグとトレースを有効にしてコンパイル すればOK。その後、プログラム内でtrace()関数を呼び出す。 これは man curses_trace に書いてある。フルトレースすると けっこうな量になる。
PutAttrCharの中でマルチバイト文字列を出力している。 PUTCというマクロを使っている。このマクロを処理した後、_nc_outputchars が2 になっているので2バイト(UCS2)処理は正しく行われている様子。
もうちょっと追ってみる。
doupdateの996行目あたり
994 UpdateAttrs(SP_PARM, normal); 995 996 NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG); 997 WINDOW_ATTRS(CurScreen(SP_PARM)) = WINDOW_ATTRS(NewScreen(SP_PARM));で、画面に表示される。そこまでは、
TransformLine(955行目)あたりから、PutRange->EmitRange->PutChar->PutAttrChar。 メモリ上は正しくUCS2な文字が入っている様子。ただ、996行目の_nc_flush(実体は flushを呼び出すだけを実行すると、文字が表示され、桁がずれる。
wnoutrefresh()のあたりにブレークポイントを仕掛け、winという構造体の中身を ダンプ。これが画面に対応しているデータを保持しているらしい。それを見ると、 win->_lineが各行データを保持しているらしい。ここには、各1文字毎に文字の値と 属性値を保持している。中身は確かに、1つの文字毎にきちんと格納されている。 ということで、内部データ(UCS2)での保持については問題なくできているはず。 ワイド文字->マルチバイト文字に変換し、エスケープシーケンスで出力する時に おかしい? _nc_getchという関数があるが、これは、チャイルドプロセスを起こす時などに、 ESCシーケンスで画面を消したりするのに使われるようだが、画面表示の時には使われない。
さらに、_nc_flush()の所にブレークポイントを仕掛け、その時の状態を見る。 1バイト文字では、1バイトずつバッファに文字が入り、そのまま出力される。 UCS文字の場合は、_nc_flush()が呼び出されてもバッファに文字が入っていない。 3回呼び出された後、バッファにUTF-8文字が入り、そのあとに1バイトの空白文字 が入っている。よって、_nc_flushに来る前に空白が付けられている。