ページ 1 / 1
プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 09:36
by 史上最悪のデスペナ
プログラムがフリーズする原因って何があるんでしょうか?
例えば、プログラム上の(動作上の)塊
A
B
C
D
とあったとき、プログラムがフリーズすることがあったとします
Bだけをコメントアウトしてもフリーズしたまま
Dだけをコメント(略)
BとDを共にコメントアウトするとフリーズしなくなる
この場合、プログラムがフリーズする原因として何が考えられるのでしょうか?
ちなみに、フリーズはプログラムが起動し、ゲームをプレイできるようになってから10数秒後ぐらいに起こります
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 09:59
by フリオ
B、Dにエラーの原因とそれを顕在化する要因がある場合、
Aに原因があって、B、Dにそれを顕在化する要因がある場合、
Aに原因があってBにそれを顕在化する要因があり、Cに原因があってDにをれを顕在化する要因がある場合、
等が考えられるので、
これだけだと、なんともいえないのでは?
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 10:52
by softya(ソフト屋)
メモリ破壊を起こしている場合は偶然の積み重ねで関係ないモジュールがフリーズする可能性は大きいです。
そこそこの大きさプログラムでは当たり前のようにあると思っておいて下さい。
※ そういう部分のガードを徹底的に行えばある程度は避ける事ができます。つまりエラー処理やらポインタの値のチェック、配列の添字範囲外のチェックなどです。想定外の値を弾きswitch文でdefaultに来たらエラーにするなどの工夫も有効でしょう。
あとフリーズしている場合デバッガで中断してフリーズする原因を特定したほうが良いと思います。
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 17:40
by 史上最悪のデスペナ
フリオ さんが書きました:Aに原因があって、B、Dにそれを顕在化する要因がある場合、
Aに原因があってBにそれを顕在化する要因があり、Cに原因があってDにをれを顕在化する要因がある場合、
これは思いつきませんでした
今まで
A
C
というプログラムでこれが動いていたので、ここは考えなくても大丈夫だろうと、勝手に考えていました
softya(ソフト屋) さんが書きました:メモリ破壊を起こしている場合は偶然の積み重ねで関係ないモジュールがフリーズする可能性は大きいです。
そこそこの大きさプログラムでは当たり前のようにあると思っておいて下さい。
そうなんですか。これが、仕事で納期直前に発覚したら・・・・・・・・・恐ろしいですね
softya(ソフト屋) さんが書きました:※ そういう部分のガードを徹底的に行えばある程度は避ける事ができます。つまりエラー処理やらポインタの値のチェック、配列の添字範囲外のチェックなどです。想定外の値を弾きswitch文でdefaultに来たらエラーにするなどの工夫も有効でしょう。
エラー処理は教えていただいたとおり、入れるようにしていますが、配列の添字とかは考えたことなかったです。(そのせいで大抵のバグはこれだったりするのですが^^;
softya(ソフト屋) さんが書きました:あとフリーズしている場合デバッガで中断してフリーズする原因を特定したほうが良いと思います。
VC++2010でのやり方がわかりません。クライアントがフリーズするとVCのほうもフリーズすることがあるようなのですが・・・・・
一度調べてみます
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 17:48
by softya(ソフト屋)
その他のテクニック。
1.どこでフリーズしているか不明なら、OutputDebugString()で通過ポイント識別子をあちこちに埋め込んでおいて通過ポイントの通過を調べるのも方法です。
2.再帰呼び出しは上限数を決めて上限を超えないようにガードする。超えたらaboat()など。
3.while/forループは上限数を超えないようにカウンタを設けてガードする。超えたらaboat()など。
あとVSが生きているならデバッガで中断できるはずです。
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 21:15
by 史上最悪のデスペナ
大まかに区切って
OutputDebugStringで大体のあたりをつけ
最後に表示されたのとその次の間で細かくやっていくと
どうもsendでフリーズしている模様です。
具体的には1704ループ目です
受信が1703回できているのかを確認する予定です
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 22:45
by 史上最悪のデスペナ
受信側では1620ループ目でフリーズ・・・・ではないようですが処理が行われなくなっているようです
クライアント側は1699ループ目でフリーズです(数値訂正)
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 23:11
by softya(ソフト屋)
sendとrecvの数が同じとは限りませんが、TCP/UDPどちらの話でしょう?
あとrecv側ではtimeoutとか処理してないんでしょうか?
数だけ見ると送信パケットが溜まりすぎているためsendに支障が出ているようにも見えますが、send側もtimeout処理を設けたほうが良いかも知れません。
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 23:15
by 史上最悪のデスペナ
UDPです。
selectを用い、さらにタイムアウトは1μs取っています
softya(ソフト屋) さんが書きました:数だけ見ると送信パケットが溜まりすぎているためsendに支障が出ているようにも見えます
そうなんですよね。その結論に達したのですが、どうしようかと・・・・・
タイムアウトを設定する・・・・ですか。その発想はなかったです。とはいえ、どうすればいいのか・・・・・少し考えて見ます
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月05日(木) 23:34
by softya(ソフト屋)
それだけとは断言できないので次のことも検討してみて下さい。winsock関係のメモリが破壊されている可能性も皆無ではありません。
1.同じようなパケットを送信動作をする小さなプログラムを作ってテスト。下に書く送信ログを送信に使っても良いかも。
2.送信ログファイルと受信ログファイルを作って送受信のパケットの突き合わせを行う。テキストにして比較はWinMargeなどを使うと便利。
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月06日(金) 19:06
by 史上最悪のデスペナ
送信側の総データ量は508kBなのに、受信側は131,568kBというふうです
データが大きすぎるのか教えてくださったソフトでは開けませんでした。
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月06日(金) 22:02
by softya(ソフト屋)
あれ?resvとsendは対のデータではないのですか? 送信側のソフトと受信側のソフトで突き合わせをすべきです。
受信が131,568kBもあるなら送信も131,568kBないと変ですが。
1600回程度で、そんなにパケットが記録されるんでしょうか?
とりあえず、大きいパケットの付きあわせが難しいのであれば、
パケット毎にmd5ハッシュを生成してmd5ハッシュを記録しただけのログを生成してみて下さい。
それなら膨大なパケットログにはならないはずです。
参考例。
「opensslを用いて、MD5のハッシュ値を求める - s-kitaの日記」
http://d.hatena.ne.jp/s-kita/20080803/1217775248
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月06日(金) 22:44
by 史上最悪のデスペナ
送信側は計算上(送信回数*送信データバイト数)と一致するので、受信側が508kにならないといけないんですが・・・・・・
これを書かなければいけませんでしたね。ごめんなさい
MD5ハッシュとかいうのをやってみます
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月10日(火) 18:30
by 史上最悪のデスペナ
MD5ハッシュが上手くできませんので暫くかかりそうです
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月10日(火) 18:33
by softya(ソフト屋)
史上最悪のデスペナ さんが書きました:MD5ハッシュが上手くできませんので暫くかかりそうです
md5導入が難しかったら、とりあえず生データのままで受信が500KB程度で打ち切って送信と受信で比べてみたらどうでしょうか?
Re: プログラムがフリーズする原因とは?
Posted: 2012年7月11日(水) 18:11
by 史上最悪のデスペナ
とりあえず、データを2回だけ送信するプログラムに変えました
受信プログラム(マルチスレッド)が上手く働いていないようです
既に何も送信してないのに受信スレッドが反応しているので・・・・・・
とりあえず、こちらは解決にしておきます
お手数をおかけしました