Aug 25, 2006

Qt3 for OS/2 #2

ポスト @ 12:04:18 | PC

引き続きQt3ライブラリ検証.

昨日詰まったビルドですが,とりあえずconfigureでStaticリンクではなくDynamicリンク(DLL利用)を選択したら無事最後まで通りました.

さてTutorialsとExamplesを一通り試してみたところ,Tutorialsは全部問題なく動きますが,ExamplesのうちいくつかがSYS3184を発生して落ちます.たとえばxframe.exeで「Select font...」ボタンを押した瞬間にSYS3184,i18n.exeでjpwを選んでOKしてもSYS3184,listviews.exeは起動した瞬間にSYS3184.これらがPsiがハングアップする原因と同一かどうかは判りませんが,少なくとも現状のQt3ライブラリは日本語環境にてなにかしら問題があるのは間違いなさそうです.

で,もうちょっと突っ込んで見てみたいわけですけど,はて,どうすりゃええのん??VisualStudioとかデバッガが存在する環境でのデバッグは仕事柄さんざんやってるんですけど,OS/2でのデバッグなんて自作CGIのprintfデバッグしかやったことないモンで,一般的にどうすればいいのか皆目見当も付きません.藁をも掴む思いでVisualAgeC++ 3.6.5を導入し,そのデバッガを起動してxframe.exeを食わせてみたら…

ソースコードデバッグ出来るやん( ´∀`)

変数の値とかは見れませんが,ソースコードとリンクしてのスタックトレース,ステップ実行等が問題なくできますし,SYS3184の例外もばっちりキャッチ出来ました.gccビルドのプログラムですけどobjにコンパイルしてilinkでリンクしているからVACPPでもデバッグ出来るのカナ?よくわかりませんがまぁ事足りたんで深くは追求するのはやめておきますw

で,問題のSYS3184発生箇所はqstring.cpp内の関数 qt_os2QString2MB() にありました.

QCString qt_os2QString2MB( const QString& s, int uclen )
...
    while ( ucLeft ) {
        rc = UniUconvFromUcs ( uo, &ucPtr, &ucLeft, (void**)&mbPtr, &mbLeft, &nonIdent );
        if ( rc == ULS_BUFFERFULL ) {
            size_t mbDone = mblen - mbLeft;
            size_t ucDone = uclen - ucLeft;
            // assume that ucLeft/mbLeft is an approximation of ucDone/mbDone
    --->    mblen = mbDone + (ucLeft * mbDone) / ucDone;
            mbBuf.resize( mblen + 1 );
            mbPtr = mbBuf.data() + mbDone;
        } else if ( rc != ULS_SUCCESS ) {
...

SYS3184はゼロ除算例外なので,ucDone が 0,つまり UniUconvFromUcs() 後に ucLeft = uclen ってことですね.ここのif 部分は

UniUconvFromUcs()でUCS文字列をネイティブ文字コードに変換するが,処理途中で出力バッファを使い果たしたら,処理済み入力データの分量からあとどのくらいバッファサイズを増やせばいいのか計算して,バッファを拡張し処理を継続する.

ってなことをやりたいようですが,出力バッファは先に

size_t mblen = uclen;
QCString mbBuf( mblen + 1 );

という風に定義されており,DBCS文字相手では最初から分量が不足しているようです.結果,UniUconvFromUcs()は1文字も処理せずULS_BUFFERFULL(バッファフル)を返し,追加分量計算で処理済み入力データが0なのにそれを除数に使ってしまってゼロ除算例外,と.

試しに

size_t mblen = uclen * 2;
QCString mbBuf( mblen + 1 );

と2倍の容量を出力バッファに与えてやったらSYS3184は発生しなくなりました.が,DBCS文字は化けてたり文字の左半分しかレンダリングされていなかったりで,一時の(今も?)Odinみたいなレベルです.DBCSサポートに関しては根本的にブラッシュアップしないとダメそうです.

ここまでの検証結果をTracに報告して今日は終了.