スポンサード リンク

T.Ishii's Software Library

HTML5 レトロ風ゲーム館

無料ブログはココログ

« コンパイラのバグ回避が厄介 | トップページ | MRWorkerの互換性 »

46が47になっていた

今は、MasterReversiの次バージョンを開発中で、バグ出しと問題点の修正を行っている。昨日はVisual Studio Community 2013の64Bitコンパイラのバグと思われる不具合の回避が厄介、と、書いたのだが、今日は、その問題も含めて大体の修正は終わったので、後、少しだ。

昨日の問題は、コンパイラのバグかどうかは定かではないのだが、問題箇所を絞り込んで行くと、以下の様な状態になっていた。

///////////////////////////////////////////////////////
// Make Index Table
///////////////////////////////////////////////////////
// Get Table Size
m_PtnIndexTableNum[engineno] = 0;
for (pattern = 0; pattern < m_ClassEvalPatternNum[engineno]; pattern++) {
  for (type = 0; type < m_ClassEvalPattern[engineno][pattern].typenum; type++) {
   m_PtnIndexTablePtnNo[engineno][m_PtnIndexTableNum[engineno]] = pattern;
   m_PtnIndexTableNum[engineno] += 1;
  }
}
str.Format(L"indexnum = %d", m_PtnIndexTableNum[engineno]);
MessageBox(NULL, str, L"test", MB_OK); // 46と表示される
tablesize = m_PtnIndexTableNum[engineno];
if (tablesize % 32) {
  tablesize /= 32;
  tablesize += 1;
  tablesize *= 32;
}
str.Format(L"indexnum = %d", m_PtnIndexTableNum[engineno]);
MessageBox(NULL, str, L"test", MB_OK); // 47 と表示される

上記のm_XXXという変数は、static変数なので、以下の様に変更してみた所、問題は無くなった。

///////////////////////////////////////////////////////
// Make Index Table
///////////////////////////////////////////////////////
// Get Table Size
indexnum = 0;
for (pattern = 0; pattern < m_ClassEvalPatternNum[engineno]; pattern++) {
  for (type = 0; type < m_ClassEvalPattern[engineno][pattern].typenum; type++) {
   m_PtnIndexTablePtnNo[engineno][indexnum] = pattern;
   indexnum += 1;
  }
}
tablesize = indexnum;
if (tablesize % 32) {
  tablesize /= 32;
  tablesize += 1;
  tablesize *= 32;
}
m_PtnIndexTableNum[engineno] = indexnum;

作者はVisual Studio のデバッガーではないので、アセンブラ出力で上記の違いは見ていない。なので、コンパイラーのバグの有無については明言しないのだが、作者的には、コンパイラーのバグかなあ、と、思っている訳だ。

念の為に書いておくと、上記の処理ルーチンは初期化処理なので、同時に動作しているワーキングスレッドはない。なので、別スレッドが上記の変数を書き替える事はない筈なので、余程の事が無い限り、上記の処理コード内で46を代入した筈の変数に47が代入される格好になっていた訳だ。

で、46が47になると何が問題なのか、というと、別処理で使用するテーブルの領域が46しか確保されていないにも関わらず、47個目の領域が参照される格好になるので、存在しないメモリ領域に対するアクセスが発生してクラッシュに至る事になる訳だ。

当然の事ながら、最適化を禁止すると、上記の二つ目のメッセージボックスでも46が表示されたし、Win32モードでビルドすれば、最適化を許可した状態でも、46が表示された。

と、いう事で、昨日の問題は、上記の変更により回避できたので、今日の時点では、64Bit版も問題なく動作する格好になっている。

ちなみに、昨日の話だと、問題はVBSなんかが追加された時の話、という事になっていたにも関わらず、上記の処理ルーチンというのは、通常時に使用されるパターン評価用のインデックス関連処理に見える筈なので、話が違うじゃないか、と、思う人もいるかもしれない。

なので、より詳細に書いておくと、MasterReversiの評価データというのは、VBSなんかの追加処理が存在しない場合、つまり、デフォルトの評価形式の場合には、処理速度的に最適化された処理コードが使われる様になっている。

つまり、VBSなんかの追加が無い場合には、上記の処理ルーチンは使われなかった訳なので、作者的にも、VBS処理絡みの処理ルーチンをチェックしたりして時間を取られた訳なのだが、VBS関連処理をスキップさせても問題が出たので、どんどん、処理ルーチンをスキップさせてみた所、パターンインデックス関連の処理をスキップした所で、クラッシュ現象が無くなった訳だ。

そして、何故、その処理ルーチンがクラッシュに至るのか、というのを確認してみた所、本来は46である筈の変数値が47になっているのが判った。

更に、その数字は何処で生成されているのか、というのを辿っていくと、上記の箇所で異常が出ているのが判った訳だ。

と、いう事で、作者的には、ある意味、無駄な時間を使った訳なのだが、上記の通りなので、実質的には、不具合の修正には1時間もかかっていない。

ただし、作者的には、コンパイラを信用できないので、実際にビルド結果を動作させてみない事には動作するかどうか判らない。

という事もあり、今回は、ソースコード的に無変更な機能についても、全機能確認を行っている訳なので、こちらについては、大きな問題にはなる筈だ。

= この記事に関連する公開中ソフト =

MasterReversi

MasterReversi

(2016/05/04追記)

« コンパイラのバグ回避が厄介 | トップページ | MRWorkerの互換性 »

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/534482/63484806

この記事へのトラックバック一覧です: 46が47になっていた:

« コンパイラのバグ回避が厄介 | トップページ | MRWorkerの互換性 »

2017年8月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

広告

プライバシーポリシー

  • 当サイトでは、第三者配信による広告(Google Adsense)サービスを利用しています。

    Google を含む第三者配信事業者は、Cookie を使用して、ユーザーのウェブサイトでの閲覧履歴に基づく広告を配信します。 Google 広告 Cookie を使用することにより、Google や Google のパートナーは当サイトや他のサイトへのアクセス情報に基づく広告をユーザーに表示できます。

    Cookieを無効にする設定およびAdsenseに関する詳細については、以下のリンクを参照下さい。

    広告 - ポリシーと規約 - Google