releaseでバッチリなのに、exeファイルではバグってる
releaseでバッチリなのに、exeファイルではバグってる
非常に困っています、相談させてください。
シューティングで、バリアを発生させる状況があるんですが
構造は、プレイヤーが実行したら、
バリアクラスをインスタンス化させて
プレイヤーの周りに発生させる、というものです。
ちなみにバリアは六つの丸い物体が
プレイヤーの周りを回る、というもので
インスタンス化はfor文でまわして、
六つ個別にインスタンス化させて発生させています。
プロジェクト上で、
デバッグで実行し、確認→バッチリOK
releaseで実行し、確認→バッチリOK
で、releaseフォルダにあるexeファイルを取り出して
その他の素材と共にフォルダに入れてexeファイルを実行。
ゲームをしてみると、そのバリアが発生しないのです。
バリアの画像が見えてないわけでもなく、
バリアの当たり判定自体存在していないっぽいんで
どうやらバリアクラスがインスタンス化されてないようです。
しかも、なぜかはわかりませんが、
確認中に何度かゲームオーバーになるわけですが
たーまに、バリアが発生するのです。
しかも6つでは無く、4つとか、、、
バリアインスタンス化のfor文は6の数字でまわしているので
4つだけで発生完了するとか、ソース上ありえません。
そもそもreleaseでプレイして、バッチリ成功しているんです。
releaseで成功しているということは変数の初期化なども
ちゃんと出来ているということですよね?
なのにexeファイルで遊ぶと
バリアが発生されないとか、、、、そんなことあるんでしょうか?
releaseでexeを吐き出す工程での
ビジュアルスタジオのバグなんでしょうか??
そんなことありえますか?
しかも、バグはバリアのところだけで
他はrelease上のゲームのまま、完璧なんです、、、、。
お願いします
考えられる原因を教えてください。
シューティングで、バリアを発生させる状況があるんですが
構造は、プレイヤーが実行したら、
バリアクラスをインスタンス化させて
プレイヤーの周りに発生させる、というものです。
ちなみにバリアは六つの丸い物体が
プレイヤーの周りを回る、というもので
インスタンス化はfor文でまわして、
六つ個別にインスタンス化させて発生させています。
プロジェクト上で、
デバッグで実行し、確認→バッチリOK
releaseで実行し、確認→バッチリOK
で、releaseフォルダにあるexeファイルを取り出して
その他の素材と共にフォルダに入れてexeファイルを実行。
ゲームをしてみると、そのバリアが発生しないのです。
バリアの画像が見えてないわけでもなく、
バリアの当たり判定自体存在していないっぽいんで
どうやらバリアクラスがインスタンス化されてないようです。
しかも、なぜかはわかりませんが、
確認中に何度かゲームオーバーになるわけですが
たーまに、バリアが発生するのです。
しかも6つでは無く、4つとか、、、
バリアインスタンス化のfor文は6の数字でまわしているので
4つだけで発生完了するとか、ソース上ありえません。
そもそもreleaseでプレイして、バッチリ成功しているんです。
releaseで成功しているということは変数の初期化なども
ちゃんと出来ているということですよね?
なのにexeファイルで遊ぶと
バリアが発生されないとか、、、、そんなことあるんでしょうか?
releaseでexeを吐き出す工程での
ビジュアルスタジオのバグなんでしょうか??
そんなことありえますか?
しかも、バグはバリアのところだけで
他はrelease上のゲームのまま、完璧なんです、、、、。
お願いします
考えられる原因を教えてください。
Re: releaseでバッチリなのに、exeファイルではバグってる
Releaseや実行ファイルでもできるやり方でデバッグしてはいかがですか?
例えば
敵も何も出ずないステージを作り
バリアとそれに関わる自機などだけを生成してみるとか
例えばバリア生成の前後でログファイルに出力してみるとか
例えば
敵も何も出ずないステージを作り
バリアとそれに関わる自機などだけを生成してみるとか
例えばバリア生成の前後でログファイルに出力してみるとか
Re: releaseでバッチリなのに、exeファイルではバグってる
exeファイルと同じフォルダにコピーした "素材" と
デバッグ実行の時に読み込まれてる "素材" が異なっているってことはありませんか?(前やらかしたミスです^^;)
デバッグ実行した時の作業ディレクトリは
プロジェクトのプロパティ->構成プロパティ->デバッグ->作業ディレクトリ で確認できます
作業ディレクトリの中身すべてをexeと同じフォルダにコピーしてみても、実行結果は変わりませんか?
デバッグ実行の時に読み込まれてる "素材" が異なっているってことはありませんか?(前やらかしたミスです^^;)
デバッグ実行した時の作業ディレクトリは
プロジェクトのプロパティ->構成プロパティ->デバッグ->作業ディレクトリ で確認できます
作業ディレクトリの中身すべてをexeと同じフォルダにコピーしてみても、実行結果は変わりませんか?
Re: releaseでバッチリなのに、exeファイルではバグってる
みなさん、回答をありがとうございます。
なにより、バリアの当たり判定が存在していませんので、画像とか素材云々じゃないと思います。
そういうチェック方法は知識にありませんでした。
そうですね、それをやってみます。hide さんが書きました: 敵も何も出ずないステージを作り
バリアとそれに関わる自機などだけを生成してみるとか
画像素材についてはもちろん確認済みですし、素材のまるごと挿げ替えもやってみました。びす さんが書きました: exeファイルと同じフォルダにコピーした "素材" と
デバッグ実行の時に読み込まれてる "素材" が異なっているってことはありませんか?
作業ディレクトリの中身すべてをexeと同じフォルダにコピーしてみても、実行結果は変わりませんか?
なにより、バリアの当たり判定が存在していませんので、画像とか素材云々じゃないと思います。
すみません、作業ディレクトリを確認すれば、なにがわかりますか?びす さんが書きました: デバッグ実行した時の作業ディレクトリは
プロジェクトのプロパティ->構成プロパティ->デバッグ->作業ディレクトリ で確認できます
そういうチェック方法は知識にありませんでした。
Re: releaseでバッチリなのに、exeファイルではバグってる
とりあえず、詰めてみました。
まず、シンプルに今回の構造を、流れで説明しますと
1、プレイヤークラスでプレイヤーがバリア発生のボタンを押す
2、ゲームマネージャークラスのバリア発生フラグが立つ
3、プレイヤークラスにて、
ゲームマネージャークラスのバリア発生フラグが立ったことを確認、
プレイヤークラス内にてバリアを作る処理実行。
4、バリア生成処理です
5、プレイヤーの周りに6つの物体が発生。
以上です。
まあ多分、どこのクラスで作るとか、構造自体の良し悪しはあると思いますが
今回のトピでは目を瞑って頂ければと思います。
で、調べた結果
フラグはちゃんと立っていました、
そしてなんとfor文の中も実行されてくれていることがわかりました。
バリアクラスじゃ無ければ、インスタンス化されて発生したのです
(例えば、通常弾クラスをインスタンス化させるようにして、六発発生させてみました)
つまり、バリアクラス自体がリストに入ってくれない、バリアクラスを認識していない?ということになります。
しかし、release実行時においてはぜんぜん成功している時点で
バリアクラス単体やexeファイル制作工程に問題があるとは思えません。。。。。。。。。。
いったいどういう原因でexeファイル上で
このようなことが起きているのでしょうか。。
あ、インクルードの記載場所が問題なのかとも考えてみたのですが、
そもそも挿げ替えて成功した通常弾クラスも
プレイヤークラスにインクルードさせたものですので
同じようにインクルードしているバリアクラスだけ問題が起きるとは思えず、、
どこに問題があるのかさっぱりです。
ビジュアルスタジオのバグとしか考えられません、、、、。
まず、シンプルに今回の構造を、流れで説明しますと
1、プレイヤークラスでプレイヤーがバリア発生のボタンを押す
2、ゲームマネージャークラスのバリア発生フラグが立つ
3、プレイヤークラスにて、
ゲームマネージャークラスのバリア発生フラグが立ったことを確認、
プレイヤークラス内にてバリアを作る処理実行。
4、バリア生成処理です
if(ゲームマネージャーのバリア発生命令flg==true){
int 角度 = 0;
//バリアクラスのインスタンス化
for(int i=0; i<6; i++){
プレイヤーバリアクラス* bdd = new cプレイヤーバリアクラス(X座標,Y座標,角度);//iはAngle
bdd->Initialize();
オブジェクトリストクラスのリストにぶち込む(bdd);
角度 += 60;
}
ゲームマネージャーのバリア発生命令flg(false);//処理終わらせる
}
以上です。
まあ多分、どこのクラスで作るとか、構造自体の良し悪しはあると思いますが
今回のトピでは目を瞑って頂ければと思います。
で、調べた結果
フラグはちゃんと立っていました、
そしてなんとfor文の中も実行されてくれていることがわかりました。
バリアクラスじゃ無ければ、インスタンス化されて発生したのです
(例えば、通常弾クラスをインスタンス化させるようにして、六発発生させてみました)
つまり、バリアクラス自体がリストに入ってくれない、バリアクラスを認識していない?ということになります。
しかし、release実行時においてはぜんぜん成功している時点で
バリアクラス単体やexeファイル制作工程に問題があるとは思えません。。。。。。。。。。
いったいどういう原因でexeファイル上で
このようなことが起きているのでしょうか。。
あ、インクルードの記載場所が問題なのかとも考えてみたのですが、
そもそも挿げ替えて成功した通常弾クラスも
プレイヤークラスにインクルードさせたものですので
同じようにインクルードしているバリアクラスだけ問題が起きるとは思えず、、
どこに問題があるのかさっぱりです。
ビジュアルスタジオのバグとしか考えられません、、、、。
Re: releaseでバッチリなのに、exeファイルではバグってる
そういう仮説を立てたのであれば、MinGWなどの他のコンパイラでコンパイルしてみて、検証してみてはいかがですか?たかし さんが書きました:ビジュアルスタジオのバグとしか考えられません、、、、。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: releaseでバッチリなのに、exeファイルではバグってる
ちなみに、発生座標や当たり判定設定などの問題かも調べました
(というかreleaseではバッチリ発生するのでこんな調査意味あるのかわかりませんが、、、)
バリアクラスがインスタンス化されれば
固定した場所に問答無用で画像が描画される様にしたんです。
そしたら、やはりそれも描画されないんです。
あと、releaseフォルダを削除し、
releaseをしなおしても意味ありませんでした。
自分では万策尽きたという感じです。
しかし、すみません、
自分まだ初心者でして、
開発環境?はビジュアルスタジオ以外なにも知りません。
MinGWというのも初めて聴きましたが、
検索してみると英語ばかりで、、、とても自分には扱えるものでは無さそうです。
そもそもこれは無料なんでしょうか?
インストールして、今作ってる全ソースを移植して、
なにかボタンを押すだけでexeファイルを作ってくれるんでしょうか?
MinGWがどういうものなのかがわかりません。
(というかreleaseではバッチリ発生するのでこんな調査意味あるのかわかりませんが、、、)
バリアクラスがインスタンス化されれば
固定した場所に問答無用で画像が描画される様にしたんです。
そしたら、やはりそれも描画されないんです。
あと、releaseフォルダを削除し、
releaseをしなおしても意味ありませんでした。
自分では万策尽きたという感じです。
みけCATさん、レスありがとうございます。みけCAT さんが書きました: MinGWなどの他のコンパイラでコンパイルしてみて、検証してみてはいかがですか?
しかし、すみません、
自分まだ初心者でして、
開発環境?はビジュアルスタジオ以外なにも知りません。
MinGWというのも初めて聴きましたが、
検索してみると英語ばかりで、、、とても自分には扱えるものでは無さそうです。
そもそもこれは無料なんでしょうか?
インストールして、今作ってる全ソースを移植して、
なにかボタンを押すだけでexeファイルを作ってくれるんでしょうか?
MinGWがどういうものなのかがわかりません。
Re: releaseでバッチリなのに、exeファイルではバグってる
あと、これを言えばさらにややこしくなるかもしれませんが
今の問題に直面しているこのゲームは一度完成させていたものでして
その時のexeファイルではちゃんとバリアが発生していたんです、、、、、。
今回、少しなにかを修正して(バリアクラスは触ってない)、
改めてバージョン2として完成させたんです。
バリアクラスは触ってないわけですから
自分もexeファイルで実行したゲームでバリア発生の確認はしていませんでした。
で、何ヶ月か過ぎてから、ゲームをプレイして
たまたまバリアを発生させる機会があったんです。
そしたらバリアが発生しないので「あれ?」と。
そこから確認、確認、の地獄が始まりました。
当時、どこを修正したのかも覚えていないせいで
前のVERSIONに戻すことも出来ません。
なぜ、バリアが発生しなくなったのか、、、
販売してしまったものなのでほんと困っています。
どうか、助けてください、、
今の問題に直面しているこのゲームは一度完成させていたものでして
その時のexeファイルではちゃんとバリアが発生していたんです、、、、、。
今回、少しなにかを修正して(バリアクラスは触ってない)、
改めてバージョン2として完成させたんです。
バリアクラスは触ってないわけですから
自分もexeファイルで実行したゲームでバリア発生の確認はしていませんでした。
で、何ヶ月か過ぎてから、ゲームをプレイして
たまたまバリアを発生させる機会があったんです。
そしたらバリアが発生しないので「あれ?」と。
そこから確認、確認、の地獄が始まりました。
当時、どこを修正したのかも覚えていないせいで
前のVERSIONに戻すことも出来ません。
なぜ、バリアが発生しなくなったのか、、、
販売してしまったものなのでほんと困っています。
どうか、助けてください、、
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: releaseでバッチリなのに、exeファイルではバグってる
つまりVisualStudioを経由して実行した場合は正しく動作するが、経由せずに直接実行した場合は確実にバグが発生するということですね?
おそらく、内部でメモリが破壊されているのではないかと思います。
VisualStudio経由で実行すると、VisualStudio内部でエミュレートのようなことが行われているのではないかと私は考えています(挙動を見ているとなんとなくそんな感じがするだけで確証はありません)。
なので、VisualStudio経由時とそうでない時とで実行結果が変わってくるのです。
VisualStudio経由だと偶然メモリが破壊されない配置になっているか、見た目に変化が出ない部分が破壊されているのではないでしょうか。
処理の順番を変えてみたり、アルゴリズムを少し変えてみたりして結果が違って来れば、それは多分どこかでメモリが破壊されています。
まあ、とりあえずまずはバージョン管理ソフトを導入するところから始めましょう。
おそらく、内部でメモリが破壊されているのではないかと思います。
VisualStudio経由で実行すると、VisualStudio内部でエミュレートのようなことが行われているのではないかと私は考えています(挙動を見ているとなんとなくそんな感じがするだけで確証はありません)。
なので、VisualStudio経由時とそうでない時とで実行結果が変わってくるのです。
VisualStudio経由だと偶然メモリが破壊されない配置になっているか、見た目に変化が出ない部分が破壊されているのではないでしょうか。
処理の順番を変えてみたり、アルゴリズムを少し変えてみたりして結果が違って来れば、それは多分どこかでメモリが破壊されています。
まあ、とりあえずまずはバージョン管理ソフトを導入するところから始めましょう。
Re: releaseでバッチリなのに、exeファイルではバグってる
回答をありがとうございます。
悪いのはvisualstudioなんでしょうか?
visualstudioをインストールしなおして
今回のプロジェクトのゲームをreleaseしなおせば直りますか?
それとも、悪いのはプロジェクトなんでしょうか?
新しくプロジェクトをつくり直して、
今回のゲームのソースをすべてペーストしてまた構築しなおせば直りますか?
検索しましたが、ピンとくる説明がありません。
それを導入すれば、今回のバグが直るのでしょうか?
はい、そうです。MoNoQLoREATOR さんが書きました: つまりVisualStudioを経由して実行した場合は正しく動作するが、
経由せずに直接実行した場合は確実にバグが発生するということですね?
メモリが破壊されているとした場合、MoNoQLoREATOR さんが書きました: おそらく、内部でメモリが破壊されているのではないかと思います。
なので、VisualStudio経由時とそうでない時とで実行結果が変わってくるのです。
悪いのはvisualstudioなんでしょうか?
visualstudioをインストールしなおして
今回のプロジェクトのゲームをreleaseしなおせば直りますか?
それとも、悪いのはプロジェクトなんでしょうか?
新しくプロジェクトをつくり直して、
今回のゲームのソースをすべてペーストしてまた構築しなおせば直りますか?
バージョン管理ソフト、というものを初めて聞きました。MoNoQLoREATOR さんが書きました: まあ、とりあえずまずはバージョン管理ソフトを導入するところから始めましょう。
検索しましたが、ピンとくる説明がありません。
それを導入すれば、今回のバグが直るのでしょうか?
Re: releaseでバッチリなのに、exeファイルではバグってる
>メモリが破壊されているとした場合、
>悪いのはvisualstudioなんでしょうか?
No
>visualstudioをインストールしなおして
>今回のプロジェクトのゲームをreleaseしなおせば直りますか?
No
>それとも、悪いのはプロジェクトなんでしょうか?
>新しくプロジェクトをつくり直して、
>今回のゲームのソースをすべてペーストしてまた構築しなおせば直りますか?
No
メモリが破壊されている場合、悪いのは「今回のゲームのソース」です。故にソースをコピペした時点で同様に問題が発生するでしょう。
ここで言われているのは、デバッガ経由(Visual Studio上から)での起動を行った際と、実行ファイルを直接起動した際にはコンピュータ内部のメモリ配置が違っており
故に実行ファイルを起動した際にのみ「目に見える」問題として出てきているのではないかということです。
目に見えなくともVisual Studio上から起動した際にもコンピュータの内部的には色々問題が起きている可能性も十分にあります。
>バージョン管理ソフト、というものを初めて聞きました。
>検索しましたが、ピンとくる説明がありません。
>それを導入すれば、今回のバグが直るのでしょうか?
No
バージョン管理システムは、簡単に言えば更新した差分を分かりやすく記録してくれる、そのうえである特定の状態に戻す等が楽に出来るもの
また複数人で開発している際の更新のすり合わせも行いやすくなるといったようなものです。
今回のプロジェクトに関してはもうどうしようもありませんが、次に取り掛かるプロジェクト、またはこれから先の更新(修正しようと試行錯誤するでしょうから)などを管理しやすく出来るようにしましょうということではないかと。
>悪いのはvisualstudioなんでしょうか?
No
>visualstudioをインストールしなおして
>今回のプロジェクトのゲームをreleaseしなおせば直りますか?
No
>それとも、悪いのはプロジェクトなんでしょうか?
>新しくプロジェクトをつくり直して、
>今回のゲームのソースをすべてペーストしてまた構築しなおせば直りますか?
No
メモリが破壊されている場合、悪いのは「今回のゲームのソース」です。故にソースをコピペした時点で同様に問題が発生するでしょう。
ここで言われているのは、デバッガ経由(Visual Studio上から)での起動を行った際と、実行ファイルを直接起動した際にはコンピュータ内部のメモリ配置が違っており
故に実行ファイルを起動した際にのみ「目に見える」問題として出てきているのではないかということです。
目に見えなくともVisual Studio上から起動した際にもコンピュータの内部的には色々問題が起きている可能性も十分にあります。
>バージョン管理ソフト、というものを初めて聞きました。
>検索しましたが、ピンとくる説明がありません。
>それを導入すれば、今回のバグが直るのでしょうか?
No
バージョン管理システムは、簡単に言えば更新した差分を分かりやすく記録してくれる、そのうえである特定の状態に戻す等が楽に出来るもの
また複数人で開発している際の更新のすり合わせも行いやすくなるといったようなものです。
今回のプロジェクトに関してはもうどうしようもありませんが、次に取り掛かるプロジェクト、またはこれから先の更新(修正しようと試行錯誤するでしょうから)などを管理しやすく出来るようにしましょうということではないかと。
Re: releaseでバッチリなのに、exeファイルではバグってる
回答ありがとうございます。
ソースも新たに打ち直せばいいのでは?」
と考えてしまうんですが、それは違うんでしょうか。
同じソースなら駄目とありますが、
同じソースで成功してた時もあったんです。
つまり、途中でメモリが破壊されたと考えた場合、
ソースの文字の問題じゃ無いんですよね?
「ソースが悪い」というニュアンスがちょっとわからないんですが、
ソースの内容では無くて、ソースのデータが悪い、ということでしょうか?
仮にソースファイルが悪いならファイルの作り直し、で解決じゃないんですか?
visualstudioも悪くないのに
結果が「今回のゲームは諦めましょう」っていうのは
なんか納得がいかないんですが、、、
メモリが破壊されないソースファイルにする方法が
無いということですよね?
プロジェクトを新たに作り直しても、ソースを打ち直しても?
でもvisualstudioのせいでは無い、、、
よくわかりません。。。。
「では最初からプロジェクトを作り直し、djann さんが書きました: メモリが破壊されている場合、悪いのは「今回のゲームのソース」です。
故にソースをコピペした時点で同様に問題が発生するでしょう。
ソースも新たに打ち直せばいいのでは?」
と考えてしまうんですが、それは違うんでしょうか。
同じソースなら駄目とありますが、
同じソースで成功してた時もあったんです。
つまり、途中でメモリが破壊されたと考えた場合、
ソースの文字の問題じゃ無いんですよね?
「ソースが悪い」というニュアンスがちょっとわからないんですが、
ソースの内容では無くて、ソースのデータが悪い、ということでしょうか?
仮にソースファイルが悪いならファイルの作り直し、で解決じゃないんですか?
visualstudioも悪くないのに
結果が「今回のゲームは諦めましょう」っていうのは
なんか納得がいかないんですが、、、
メモリが破壊されないソースファイルにする方法が
無いということですよね?
プロジェクトを新たに作り直しても、ソースを打ち直しても?
でもvisualstudioのせいでは無い、、、
よくわかりません。。。。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: releaseでバッチリなのに、exeファイルではバグってる
簡単に言うとプログラムコードにバグが有り、条件次第(メモリ空間の配置やメモリの初期値などなど)でメモリ破壊バグを引き起こしていますよって話です。
同じプログラム・ロジックであるかぎりバグは再発する可能性があります。
なので、visualstudioでも、プロジェクトの問題でも、打ち込みの問題でもありません。
ご自身がソースコードとして書かれたロジックに問題が隠れています。
これは、ご自身のプログラムのバグを取れば問題は解決します。
【補足】
これらは俗に言う落ちバグ・不思議現象バグですが、特定条件下でしか発生し無いのでプロでも苦しむ代物です。[落ちバグに限定していたので修正]
出る確率が高く出来るのなら俺イケてる!と思ってしまうぐらい再現だけでも大変なのもあります。
[追記]それとメモリ破壊バグではなくタイミングバグかも知れません。
【補足の補足】
>で、何ヶ月か過ぎてから、ゲームをプレイして
>たまたまバリアを発生させる機会があったんです。
>そしたらバリアが発生しないので「あれ?」と。
>そこから確認、確認、の地獄が始まりました。
確実にバグが出るならあなたはラッキーです。
すぐさま、ソースコードをバージョン管理して、バリヤが出る場合とでない場合の差分コードを見つけましょう。
同じプログラム・ロジックであるかぎりバグは再発する可能性があります。
なので、visualstudioでも、プロジェクトの問題でも、打ち込みの問題でもありません。
ご自身がソースコードとして書かれたロジックに問題が隠れています。
これは、ご自身のプログラムのバグを取れば問題は解決します。
【補足】
これらは俗に言う落ちバグ・不思議現象バグですが、特定条件下でしか発生し無いのでプロでも苦しむ代物です。[落ちバグに限定していたので修正]
出る確率が高く出来るのなら俺イケてる!と思ってしまうぐらい再現だけでも大変なのもあります。
[追記]それとメモリ破壊バグではなくタイミングバグかも知れません。
【補足の補足】
>で、何ヶ月か過ぎてから、ゲームをプレイして
>たまたまバリアを発生させる機会があったんです。
>そしたらバリアが発生しないので「あれ?」と。
>そこから確認、確認、の地獄が始まりました。
確実にバグが出るならあなたはラッキーです。
すぐさま、ソースコードをバージョン管理して、バリヤが出る場合とでない場合の差分コードを見つけましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: releaseでバッチリなのに、exeファイルではバグってる
ソースとはソースコードのことです。
かなり強引な例ですが次の二つのコードを参照してください。
これと
これです。(環境によってはb.is_available()に到達する前に止まってしまうかもしれませんが)
どちらもほとんど変化がなく、特にbarrierクラスなんて一切手を加えていません。
がfoo()関数にバグがあるのはどこを見ても明らかですよね?
そのバグの具合や、呼び出しのタイミングによって、barrierクラスを何も書き換えていないのに違う結果が出てしまうことになるわけです。
>「では最初からプロジェクトを作り直しソースも新たに打ち直せばいいのでは?」
>と考えてしまうんですが、それは違うんでしょうか。
例えばこのコード、新たなプロジェクトを作成したからといってバグが直るものでしょうか?
もちろん前のプロジェクトのコードを参照しながら自身で入力しなおすといった場合であれば、途中で「ここはバグだ」と認識して修正されることもあるかもしれませんので、問題が解決するかもしれません(それ以前に打ち間違えてバグを混入させる可能性の方が高そうですが)。
「プログラムは思った通りには動かない。書いたとおりに動く」とは誰の言った言葉だったでしょうか。
メモリが破壊されないソース(コード)にする方法は、例えばこの例で言えば「std::memset()に渡しているサイズを適切なものにする」です。完全に無いわけではなく「自身(またチームメイト)の書いたコードを全て疑い、破壊を行っているであろう部分を全て片づけるという莫大な労力が掛かり、なおかつ『そのプロジェクトを見る事の出来ない者には一切手が付けられない』作業」を行えば修正されるでしょう。
メモリが破壊されていると限った訳ではありませんが、少なくともバグが潜んでいることは間違いなく、またそれが実行する環境(デバッガ接続の有無)により変わるということは確かです。その修正は前述したようにソースコード(書いたC/C++言語の文字)を修正することでしか解決はされないでしょう。
(たまにオブジェクトファイルの不整合などがあったりもするので、いったんリビルドを行ってみてみるのも良いとは思います)。
かなり強引な例ですが次の二つのコードを参照してください。
#include <iostream>
#include <setjmp.h>
class barrier {
bool m_available;
public:
barrier() : m_available( false ){}
~barrier(){}
void set_available(){
this->m_available = true;
}
void is_available(){
if ( this->m_available ){
std::cout << "Available." << std::endl;
} else {
std::cout << "Unavaiable." << std::endl;
}
}
};
jmp_buf buf;
void foo(){
char text[ 4 ] = {};
std::memset( text, 0x01010101, 0x08 );
std::cout << text << std::endl;
longjmp( buf, 1 );
}
int main()
{
barrier b;
if ( !setjmp( buf ) ){
foo();
}
b.is_available();
std::cin.get();
}
#include <iostream>
#include <setjmp.h>
class barrier {
bool m_available;
public:
barrier() : m_available( false ){}
~barrier(){}
void set_available(){
this->m_available = true;
}
void is_available(){
if ( this->m_available ){
std::cout << "Available." << std::endl;
} else {
std::cout << "Unavaiable." << std::endl;
}
}
};
jmp_buf buf;
void foo(){
char text[ 4 ] = {};
std::memset( text, 0x01010101, 0xF0 );
std::cout << text << std::endl;
longjmp( buf, 1 );
}
int main()
{
barrier b;
if ( !setjmp( buf ) ){
foo();
}
b.is_available();
std::cin.get();
}
どちらもほとんど変化がなく、特にbarrierクラスなんて一切手を加えていません。
がfoo()関数にバグがあるのはどこを見ても明らかですよね?
そのバグの具合や、呼び出しのタイミングによって、barrierクラスを何も書き換えていないのに違う結果が出てしまうことになるわけです。
>「では最初からプロジェクトを作り直しソースも新たに打ち直せばいいのでは?」
>と考えてしまうんですが、それは違うんでしょうか。
例えばこのコード、新たなプロジェクトを作成したからといってバグが直るものでしょうか?
もちろん前のプロジェクトのコードを参照しながら自身で入力しなおすといった場合であれば、途中で「ここはバグだ」と認識して修正されることもあるかもしれませんので、問題が解決するかもしれません(それ以前に打ち間違えてバグを混入させる可能性の方が高そうですが)。
「プログラムは思った通りには動かない。書いたとおりに動く」とは誰の言った言葉だったでしょうか。
メモリが破壊されないソース(コード)にする方法は、例えばこの例で言えば「std::memset()に渡しているサイズを適切なものにする」です。完全に無いわけではなく「自身(またチームメイト)の書いたコードを全て疑い、破壊を行っているであろう部分を全て片づけるという莫大な労力が掛かり、なおかつ『そのプロジェクトを見る事の出来ない者には一切手が付けられない』作業」を行えば修正されるでしょう。
メモリが破壊されていると限った訳ではありませんが、少なくともバグが潜んでいることは間違いなく、またそれが実行する環境(デバッガ接続の有無)により変わるということは確かです。その修正は前述したようにソースコード(書いたC/C++言語の文字)を修正することでしか解決はされないでしょう。
(たまにオブジェクトファイルの不整合などがあったりもするので、いったんリビルドを行ってみてみるのも良いとは思います)。
Re: releaseでバッチリなのに、exeファイルではバグってる
ソフト屋さん、djannさん、回答ありがとうございます。
まず、djannさんのソースの内容だと
ちゃんとreleaseやデバッグでも発見できると思うんです。
でも私のケースはreleaseではバッチリ成功していて
実行ファイルで初めて発生するバグなんです。
visualstudioが悪くないとすれば、
visualstudioがGOサインを出して
実際にこちらの思惑通りに実行してくれている「ソース」なはずです。
それがexeにした途端発生するわけです。
なのでちょっとケースが、違う気がするんです、、、、。
しかもこちらは妙に不特定なバグです。
djannさんのソースでのバグと違い、
こちらはなにが起きているのか検討がつきません。
例えば、今、ソースを色々触って原因を突き止めようとしているのですが
(release後に作成した実行ファイルでのみで発生するバグなので確認も大変です)
現在、新たにわかった情報があります。
●相談を出してからバリアクラス内はなにもいじっていないのに
新しいバリアクラスを作っている最中に
実行ファイルを実行して一番最初のゲームプレイ時の
一番最初のバリア発生命令のみ、シッカリバリアが発生するようになった。
しかし、その次にバリアを発生させるとバリアが発生しない。
しかも新しいバリアクラスを作ったが、まだ挿げ替えていないのに、です。
●バリアがリスト内に存在したらフラグが立つようにしたら、
どうやら発生しないバリア処理の時も、
リスト内には一瞬入っているようです。で、1フレームで消滅していると。
しかしココが問題で、バリアの消滅処理のところには
消滅と同時に、サウンドを鳴らしたり、
再度バリアを発生できる確認のためにバリアの消滅する数を数えたりしてるのですが
それらの処理がされていないのです。
つまり、こちらの記載している消滅方法では無い「消滅」なんです。
自分のソースからは有り得ないです。
私のプログラム文のせいでは無いような気がします。
確かに「メモリ破壊」が起きている気もします。
シックリくるのです、その言葉が。
リスト内に入ったらすぐ消滅しているわけですし、、、
しかし、例えばこれが自分の書いたロジックやソースのせいならば
releaseやデバッグで検証している時点でその消滅は起きるはずです。
でもそこでは何度やっても起きないんです。
シッカリと思惑通りに動いてくれているんです。
それっておかしくないですか?
まず、djannさんのソースの内容だと
ちゃんとreleaseやデバッグでも発見できると思うんです。
でも私のケースはreleaseではバッチリ成功していて
実行ファイルで初めて発生するバグなんです。
visualstudioが悪くないとすれば、
visualstudioがGOサインを出して
実際にこちらの思惑通りに実行してくれている「ソース」なはずです。
それがexeにした途端発生するわけです。
なのでちょっとケースが、違う気がするんです、、、、。
しかもこちらは妙に不特定なバグです。
djannさんのソースでのバグと違い、
こちらはなにが起きているのか検討がつきません。
例えば、今、ソースを色々触って原因を突き止めようとしているのですが
(release後に作成した実行ファイルでのみで発生するバグなので確認も大変です)
現在、新たにわかった情報があります。
●相談を出してからバリアクラス内はなにもいじっていないのに
新しいバリアクラスを作っている最中に
実行ファイルを実行して一番最初のゲームプレイ時の
一番最初のバリア発生命令のみ、シッカリバリアが発生するようになった。
しかし、その次にバリアを発生させるとバリアが発生しない。
しかも新しいバリアクラスを作ったが、まだ挿げ替えていないのに、です。
●バリアがリスト内に存在したらフラグが立つようにしたら、
どうやら発生しないバリア処理の時も、
リスト内には一瞬入っているようです。で、1フレームで消滅していると。
しかしココが問題で、バリアの消滅処理のところには
消滅と同時に、サウンドを鳴らしたり、
再度バリアを発生できる確認のためにバリアの消滅する数を数えたりしてるのですが
それらの処理がされていないのです。
つまり、こちらの記載している消滅方法では無い「消滅」なんです。
自分のソースからは有り得ないです。
今回の私のレスでも書きました通り、softya(ソフト屋) さんが書きました: ご自身がソースコードとして書かれたロジックに問題が隠れています。
これは、ご自身のプログラムのバグを取れば問題は解決します。
私のプログラム文のせいでは無いような気がします。
確かに「メモリ破壊」が起きている気もします。
シックリくるのです、その言葉が。
リスト内に入ったらすぐ消滅しているわけですし、、、
しかし、例えばこれが自分の書いたロジックやソースのせいならば
releaseやデバッグで検証している時点でその消滅は起きるはずです。
でもそこでは何度やっても起きないんです。
シッカリと思惑通りに動いてくれているんです。
それっておかしくないですか?
Re: releaseでバッチリなのに、exeファイルではバグってる
1. 先ほど記述したコードについて
先ほどのコードは
「その部分をいくら見ても正しく、書き換えていないのに『他の部分の変更によって』特定の機能がおかしくなることもある」
ということをを示す為の意図したソースコードですので、そこを取り違えないでください。
もちろん先ほどのコードは「問題を起こす」為に書かれており、メモリ破壊による他への影響を「見えるようにかなり単純化している」ので「常に発生」します。
これは考え方を示しているものなので、そのものズバりでないが故にケースが違うという認識は正しくないと思います。
・メモリ破壊という言葉について
メモリ破壊は自然に起きるものではなく貴方・・・とは限りませんが、少なくともそのプロジェクト内に含まれるコード(ここでいうコードとはソースコードに限定されず、まさにプロジェクトに含まれる全てのコードを意味します)が引き起こしているものです。お間違えなきよう。
・新たに分かった情報に対して
>バリアクラス内はなにもいじっていないのに~~
充分あり得る事ですね。コードが増えるだけでも実行時のメモリ配置は少なからず変化します。
>リスト内に存在したらフラグが立つようにしたら~~
何度も言っている通り「バリアがおかしな挙動をするからと言ってバリア処理に関係するソースコードが影響するという訳では無い」のです。記載している消滅方法ではないというのは、むしろ外部からどこが書き換えられているのかが特定しやすくなるのではないでしょうか?
>自分の書いたロジックやソースのせいならば~~
言われているのは「自分の書いたロジックのせい」であって「バリアの処理のせい」ではありません。おかしいところは何もありません。
Visual Studio上で起動すると起きずに実行ファイルの直接起動では発生すると言ってますが、その両者ではメモリの使い方が変わる可能性があるということをまず認識してください。
例えば1プロセスで使用可能な仮想アドレス空間は規定されていますが、デバグ用の情報が入ることで使用可能な実質的な量は変わります。
間にデバグ用の情報が取られることで32Byteあった隙間が24Byteになっていたり場合new char[ 28 ];でとられるメモリの位置は大幅に変わります。
つまり先ほど私が書いたバグサンプルでいうchar textとbarrier bのメモリ上での位置関係が変わるという事になります(実際にはあのサンプルでは自動ストレージに確保しているので位置関係が大きく変わることはありませんが)。そうすると、必然的に「Visual Studio上では起きなかったのに実行ファイルで起動すると起きるバグ」のようなものが発生します。
例えば私が仕事で携わったプロジェクトでは「Visual Studio上から起動した場合のみ、メモリを4096MB載せたシステム上で、特定のユーザ名を持つ相手と通信対戦を行い、僅差で負けるとエンディングが流れる」というバグがありました(もちろんその状態ではリリースされていませんが)。
最終的につきとめた直接的な原因は、画面へ文字列の描画を行う際にアクセスしていた変数が、特定の文字の並びだった場合にのみ範囲外へアクセスしており、そのアクセス先がVisual Studio上から起動した場合には「たまたま」ゲームのフローを管理する部分へアクセスされていたというものでした。一見何の問題もない部分が「他の部分のバグにより」、昔から使われていた信頼性の高いコードだったにも関わらず問題をおこしていました。
自分の方には問題が無い、他の技術者たちが長い年月をかけて作り上げてきたもの(Windowsやデバッガというシステム、それらを利用するVisual Studio)が悪いんだという考えを捨てましょう。
ひとまず、メモリ破壊が行われているのであればバリアクラスの登録先を多重化したり、実体で管理しているところを動的に確保したりすると挙動が変わってくるのではないかと思いますがいかがでしょうか?
また バリアクラス *m_barrier[ 6 ]; のように持っている部分があるのでしたら、その前後の配列や実体で確保しているクラスの処理が問題となっていることも多いのでそちらを見てみる、クラス内でのメモリレイアウトを変えてみる等して影響部分が変わるか、変わるならどこへ影響が出るか試してみる等も行ってみるといいかもしれません。
プロジェクト中に単純に配列があるのであればそれを全てstd::arrayに置き換え、添え字アクセスをしている部分を全てat()メンバ経由で実行してみてDebugビルドを行う等・・・は流石に全部置き換えるのは厳しいかもしれませんが。
同様にoperator new[]で確保している部分があるのなら、その確保数と実際にアクセスしている添え字が間違っていないか(間違っているなら何らかの出力を行う等で)確認して、少しずつつぶしていきましょう。
先ほどのコードは
「その部分をいくら見ても正しく、書き換えていないのに『他の部分の変更によって』特定の機能がおかしくなることもある」
ということをを示す為の意図したソースコードですので、そこを取り違えないでください。
もちろん先ほどのコードは「問題を起こす」為に書かれており、メモリ破壊による他への影響を「見えるようにかなり単純化している」ので「常に発生」します。
これは考え方を示しているものなので、そのものズバりでないが故にケースが違うという認識は正しくないと思います。
・メモリ破壊という言葉について
メモリ破壊は自然に起きるものではなく貴方・・・とは限りませんが、少なくともそのプロジェクト内に含まれるコード(ここでいうコードとはソースコードに限定されず、まさにプロジェクトに含まれる全てのコードを意味します)が引き起こしているものです。お間違えなきよう。
・新たに分かった情報に対して
>バリアクラス内はなにもいじっていないのに~~
充分あり得る事ですね。コードが増えるだけでも実行時のメモリ配置は少なからず変化します。
>リスト内に存在したらフラグが立つようにしたら~~
何度も言っている通り「バリアがおかしな挙動をするからと言ってバリア処理に関係するソースコードが影響するという訳では無い」のです。記載している消滅方法ではないというのは、むしろ外部からどこが書き換えられているのかが特定しやすくなるのではないでしょうか?
>自分の書いたロジックやソースのせいならば~~
言われているのは「自分の書いたロジックのせい」であって「バリアの処理のせい」ではありません。おかしいところは何もありません。
Visual Studio上で起動すると起きずに実行ファイルの直接起動では発生すると言ってますが、その両者ではメモリの使い方が変わる可能性があるということをまず認識してください。
例えば1プロセスで使用可能な仮想アドレス空間は規定されていますが、デバグ用の情報が入ることで使用可能な実質的な量は変わります。
間にデバグ用の情報が取られることで32Byteあった隙間が24Byteになっていたり場合new char[ 28 ];でとられるメモリの位置は大幅に変わります。
つまり先ほど私が書いたバグサンプルでいうchar textとbarrier bのメモリ上での位置関係が変わるという事になります(実際にはあのサンプルでは自動ストレージに確保しているので位置関係が大きく変わることはありませんが)。そうすると、必然的に「Visual Studio上では起きなかったのに実行ファイルで起動すると起きるバグ」のようなものが発生します。
例えば私が仕事で携わったプロジェクトでは「Visual Studio上から起動した場合のみ、メモリを4096MB載せたシステム上で、特定のユーザ名を持つ相手と通信対戦を行い、僅差で負けるとエンディングが流れる」というバグがありました(もちろんその状態ではリリースされていませんが)。
最終的につきとめた直接的な原因は、画面へ文字列の描画を行う際にアクセスしていた変数が、特定の文字の並びだった場合にのみ範囲外へアクセスしており、そのアクセス先がVisual Studio上から起動した場合には「たまたま」ゲームのフローを管理する部分へアクセスされていたというものでした。一見何の問題もない部分が「他の部分のバグにより」、昔から使われていた信頼性の高いコードだったにも関わらず問題をおこしていました。
自分の方には問題が無い、他の技術者たちが長い年月をかけて作り上げてきたもの(Windowsやデバッガというシステム、それらを利用するVisual Studio)が悪いんだという考えを捨てましょう。
ひとまず、メモリ破壊が行われているのであればバリアクラスの登録先を多重化したり、実体で管理しているところを動的に確保したりすると挙動が変わってくるのではないかと思いますがいかがでしょうか?
また バリアクラス *m_barrier[ 6 ]; のように持っている部分があるのでしたら、その前後の配列や実体で確保しているクラスの処理が問題となっていることも多いのでそちらを見てみる、クラス内でのメモリレイアウトを変えてみる等して影響部分が変わるか、変わるならどこへ影響が出るか試してみる等も行ってみるといいかもしれません。
プロジェクト中に単純に配列があるのであればそれを全てstd::arrayに置き換え、添え字アクセスをしている部分を全てat()メンバ経由で実行してみてDebugビルドを行う等・・・は流石に全部置き換えるのは厳しいかもしれませんが。
同様にoperator new[]で確保している部分があるのなら、その確保数と実際にアクセスしている添え字が間違っていないか(間違っているなら何らかの出力を行う等で)確認して、少しずつつぶしていきましょう。
Re: releaseでバッチリなのに、exeファイルではバグってる
>リスト内には一瞬入っているようです。で、1フレームで消滅していると。
リストに入っているかどうか がわかるなら
いろんな場所に「入ってるかどうかを調べて結果を何かしら表示なりする」ような処理を
差し挟んでみて消滅(?)に至らしめている処理箇所を絞り込んでいく
…ようなことはできませんか?
リストに入っているかどうか がわかるなら
いろんな場所に「入ってるかどうかを調べて結果を何かしら表示なりする」ような処理を
差し挟んでみて消滅(?)に至らしめている処理箇所を絞り込んでいく
…ようなことはできませんか?
オフトピック
自分の失敗を思い出した
http://dixq.net/forum/viewtopic.php?f=78&t=14198
http://dixq.net/forum/viewtopic.php?f=78&t=14198