【Jane】p2proxy Part9【p2.2ch.net】

このエントリーをはてなブックマークに追加
247♪ ◆/y.Ychk2JQ
http://pc12.2ch.net/test/read.cgi/software/1258384764/277 の件ですが。

この問題が起きる原因はTextOutWに問題があるような感じでした。

0xBCA、 0xBEA の組み合わせが16回の場合は特に目立った問題はありません。
17回、18回になると、表示に問題が起きますがメモリリークは起こしませんでした。
19回目になると関数呼び出ししても表示されず、メモリリークが発生します。

ということでこの不具合は特定のユニコード文字をTextOutWに WideString.Length=32 を超える文字列として渡すと発生します。

対処法としては TextOutW 自体をラップする関数を作るなどして
TextOutWに投げるWideString のLengthを常に32以下に維持するようにすれば問題はないように思えます。
248♪ ◆/y.Ychk2JQ :2009/11/22(日) 15:06:02 ID:q6HL2B5V0 BE:998577465-PLT(22223)
で、めっちゃくちゃの憶測なんですけど、、、

メモリリークの原因は TextOutW の内部処理中にエラーでトラップされているため、
TextOutW(もしくは内部的な部分)で確保されたメモリが開放されずにたまっていく、という感じですかね。

それと、TextOutWの最後に渡す引数(cbString)には文字サイズを渡すわけなんですが
ここに実際の文字サイズの倍ぐらいの値を指定すると症状は発生しませんでした。
(当然画面上にも無駄な文字列が表示されちゃうので対処方法にはならないけど)

0xBCA、 0xBEA の組み合わせで20回とすると、文字サイズは40ってことになりますね。
cbStringに渡すのもこのサイズになるんですが、
TextOutWの内部でも同等サイズのメモリを確保しているのではないかと思います。
内部ではメモリ的には0xBCA、 0xBEAの2文字分(4バイト)しか確保していないが
表示するため文字コードをチェックする際に組み合わせがおかしいので0xBCA、(???)、0xBEA という感じで実際には3文字分のメモリを使ってしまっているんじゃないかなと。
結果的に実際の確保したメモリとアクセスが発生するメモリサイズが違い、
未確保分のメモリアクセスの時にエラー(メモリバッファオーバーフロー)が発生するのではないかなと思います。
#オーバーフローがあっても必ずエラーになるとは限らないので、その際は表示が行われ、確保していたメモリも開放される
#もしそのオーバーフローでスタックなどを破壊した場合に関数が正常に終了せずメモリリークを発生させる
#そのうち落ちる

でもってすげー適当に言っているので鵜呑みは禁止です。
249♪ ◆/y.Ychk2JQ :2009/11/22(日) 15:11:19 ID:q6HL2B5V0 BE:466003627-PLT(22223)
>表示するため文字コードをチェックする際に組み合わせがおかしいので0xBCA、(???)、0xBEA という感じで実際には3文字分のメモリを使ってしまっているんじゃないかなと。

ここ間違った。
削除削除。
250♪ ◆/y.Ychk2JQ :2009/11/22(日) 15:13:29 ID:q6HL2B5V0 BE:1864011078-PLT(22223)
あれ?
いや間違ってないかも?
これを削除→>>249
251♪ ◆/y.Ychk2JQ :2009/11/22(日) 15:23:47 ID:q6HL2B5V0 BE:932005474-PLT(22223)
>それと、TextOutWの最後に渡す引数(cbString)には文字サイズを渡すわけなんですが
>ここに実際の文字サイズの倍ぐらいの値を指定すると症状は発生しませんでした。
>(当然画面上にも無駄な文字列が表示されちゃうので対処方法にはならないけど)

ここにもうひとつ。
症状は発生しなかったのはたまたまですね。
「実際の文字サイズの倍ぐらいの値 - 実際の文字サイズ」 の部分にある文字列はいわばゴミです。
で、このゴミの中に同様の症状を引き起こすユニコード文字と同等のバイナリデータがいればやっぱり症状は発生すると思います。
252名無しさん@お腹いっぱい。:2009/11/22(日) 15:25:54 ID:Mnkyr87G0
に、日本語で・・・お、おk・・・
253♪ ◆/y.Ychk2JQ :2009/11/22(日) 15:57:50 ID:q6HL2B5V0 BE:2396585489-PLT(22223)
そんで、Janeではドラッグすると・・・ということですが、

Janeでは 
・文字列の出力は行単位で行う
・「連続した選択されている文字列(背景が青色になる部分)・・・(1)」/「連続した選択されていない文字列・・・(2)」単位で行う
#全体的な表示に関してはもっと複雑になっています。。。
#このユニコード文字列に関してはというで解釈してください。

つまり
・通常は1行で32文字を超えていたためエラーで表示されていなかった
・文字列をドラッグ(範囲選択)すると、ドラッグの位置によって(1)の文字数と(2)の文字数が変化する
・(1)と(2)の文字数がそれぞれ、約32文字を超えると表示されないが、それ以下の場合に限って正常に(と思われるが)表示される。

この一度に表示する文字数の変化によって表示されるときとされないときという状態が生まれる。
そして「表示されないとき」にはメモリリークは常に発生している。

どういうことかというと、ドラッグを行わなくてもスレビューのスクロールなどによって「再描画」が必要な状態になればJaneが落ちる可能性は高い。
だから「ドラッグしなければいいんだろ?」というのは間違いだと思います。
意図的にドラッグするよりもスクロールなどによる「再描画」は回数が少ないので特に表面化しないだけという感じですね。
まだ未対応のJaneを使っている皆さんはご注意ください。
254♪ ◆/y.Ychk2JQ :2009/11/22(日) 16:04:05 ID:q6HL2B5V0 BE:665718454-PLT(22223)
追記:
ポップアップさせるだけでも同様ですので注意が必要です。