Bug #75

(V6.33)シークを素早く断続的に繰り返すと落ちる場合がある

Redmine Adminほぼ11年前に追加. ほぼ11年前に更新.

ステータス:終了開始日:2013/02/09
優先度:通常期日:2013/02/16
担当者:-進捗 %:

100%

カテゴリ:-作業時間の記録:-
対象バージョン:-

説明

状況(2013.02.16)

V6.34にて対応済み。

(原因)
Museが演奏時に駆動するタイマーコールバックと、そのタイマーの停止は別のスレッドでの実行である。
よってコールバックが実施されている最中にタイマー停止が起こる可能性があるが、その対処を行っていなかった。
タイマー停止直後に音源のクローズを実施しており、結果としてクローズ処理と発音処理が競合してハングしたと思われる。

(再現性)
タイマー停止から音源クローズまでの間に、最後のコールバックによる演奏処理が完了しきれない場合に限り発現するため、
再現性は極めて低く、再現させるためには以下のような状況が必要であった。
・演奏開始と停止が短周期かつ高頻度に繰り返される(左右カーソルキーの高速な押下/開放による断続的シーク操作など)
・演奏処理が充分に重い(多量のデータ、譜面モニタ、サウンドフォントなどの高負荷状態)
・タイマー停止から音源クローズまでが速やかに処理される(性能の良いPC。Win7搭載のPCは往々にしてパフォーマンスが良い)

(経緯)
V6.27からV6.28にバージョンアップする際、高速化のために演奏停止の処理に手を加えた。
従来、音源のクローズ命令を確実に実施するために適度なインターバルを与えていたが、
それが無くとも安定して音源処理が完了することを確認したため、V6.28でそのインターバルを取り払った。
しかしこのインターバルは、本件で発現したタイプの不具合を抑止するという別の意味も偶然持ち合わせていた。
(当時は、抑止を意図してインターバルを与えた訳ではなかった)
このインターバルは、タイマーを停止してから音源をクローズするまでに、適度な時間間隔を与える事になり、
結果として、タイマー停止後に残存するタイマーコールバック内の演奏処理をすべて完了させる余裕を生み出していた。
V6.28でその余裕時間を取り払ったため、今回の症状が発生する事となった。

(検証)
追跡中、midiOutShortMsg()に、クローズ後の音源ハンドルを渡していることが原因であると分析したこともあったが、
強制的にそのような状況を作り上げた実験では、midiOutShortMsg()は、
MMSYSERR_INVALHANDLE(指定されたデバイスハンドルが無効)を返却するのみで、ハングすることは無かった。
この挙動は、音源ハンドルをNULLにしても、またランダムで意味のないハンドル値を指定しても同様であった。
このことから、音源ハンドル値の不正がハングの引き金になっているわけではなく、
音源管理モジュールの深部においてクローズ処理と発音処理の競合が起きた際にハングすると推測している。
よって、この競合状態を回避することが、本質的な解決につながると結論した。

(対処)
タイマー停止時に適度なインターバルを与え、その後にMIDI音源のクローズを実施する事とした。
またタイマーコールバック(演奏処理)でのMIDI音源へのデータ送信直前にタイマー状況をチェックし
もし停止していたら送信しないようガードを掛けた。

概要(2013.02.09)

●報告1
メインの画面で、再生しながらCtrl+→,←でマーク間を行ったり来たりすると、落ちることがあるようです。
いっぱい動かすとなります。1、2回じゃ発生しません。最低で4回、最高で30回ぐらいでした。
譜面モニタを表示した時にだけ起きるようです。
だから音源と言うよりは描写系の何かだと思います。
あと、データによっても起きるか起きないかが変わります。
小さめのデータは起きないようで(起きるのかもしれませんが30回ぐらいでは起きませんでした)
大きめのデータ(というより16メンバーをフルに使っていると起きやすい)だと起きます。
ちなみにMARK文のあるデータです。

●報告2
譜面モニタを表示しなくても、メインの画面で再生しながら
Ctrl+→を数回押すと落ちたり落なかったりします。
因みに落ちた時の画像です。↓

●報告3
音源の話があったので色々試してみると、
MSGSやサウンドフォントなどの、ソフト音源系(音源のオープンに時間がかかる系)が出やすいようです。
現行バージョンだとサウンドフォントなら譜面モニタなしですぐに落ちます。
テスト版だと、譜面モニタなしだと今のところ落ちてないです。

●報告4
[→]だけでも落ちますね。[→]を押した時に落ちるようです。
1秒に2、3回程度の押し方で、半分位で落ちました。

●報告5
V6.29でも落ちます。

●報告6
V6.27では落ちない模様です。V6.28では落ちます。

●報告7
逆アセンブルして解析すると、どうやら、次のような呼び出しが発生した後、コケているようでした。
midiOutShortMsg(hmo, 0x003c4d9d);

第二引数は何の変哲もないノートオンですので問題なしとして、
hmoの値が古い値をとっていたり、どこかで値が破壊されていたり、
などという可能性はないでしょうか?

●報告8
その後の調査の結果、「hmoがレジスター上からメモリー上にコピーされていない」ということはありえない、ということは判明しました。
ですので可能性としては、

(1) midiOutOpen()が完了する前に演奏を開始してしまうケースがある
(2) hmoが、バッファオーバーフロー等の影響で破壊される
の2つに絞られたことになると思います。

●報告9
「クローズ後、hmoにNULLが設定される前に演奏処理を行っている」ではないかと考えます。

<状況の整理>

・押下キーは[→]のみで落ちる([CTRL]や[SHFIT]の併用不要)
・マウスグリップによるシークでも落ちる
・何度かシークを素早く断続的に実施していると、いつか[→]を押下した瞬間に落ちるようである
・譜面モニタを表示したり、音源をサウンドフォントにしたり負荷を高めると落ちやすい
・MARK文が無くても落ちる

<症状を確認した環境>

[OS]
Win7(Home)
Win7(Pro32)

[Muse]
V6.33
V6.29
V6.28

[音源]
SC-88Pro
Microsoft GS Wavetable Synth

関連するチケット

関連している Release #167: Muse V6.33 終了 2013/02/07

履歴

#1 Redmine Adminほぼ11年前に更新

  • 説明 を更新 (diff)

#2 Redmine Adminほぼ11年前に更新

  • 期日2013/02/16 にセット
  • ステータス新規 から 終了 に変更
  • 開始日2013/12/31 から 2013/02/09 に変更
  • 進捗 %0 から 100 に変更

他の形式にエクスポート: Atom PDF