• ベストアンサー

CRCの計算でエラー

VisualC++2008でプログラミングしております。簡単なモデムプログラムを作っているのですが、エラー検出で利用するCRCでつまづいています。具体的には、特定のファイルを送信しようとすると常にエラーが発生したと判断され、再送要求をし続けてしまいます。 以前、チェックサムでXORを利用した時も同様なことが発生したので、XORの計算があやしいのかなと感じています。デバッグでは正しく計算されるようなのですが、リリースで実行すると上記のようになります。 どなたかアドバイスを頂ければと思います。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

>また,特定のファイルを転送しようとしたときのみこの症状が出ます.そしていつも同じ場所でとまってしまいます.(例:13,447バイトのJPEGファイルを転送しようとすると,2816バイトまでしか転送されない)デバッグではその場所でエラーが出たりすることはありませんでした. であれば、データを転送する際に、128バイトのデータと、計算したCRCを画面かログファイルに出力してみてはどうでしょう。デバッグとリリースで同じ値になっているかどうか確認できると思います。 果たしてエラーの原因がCRCの計算にあるのか、それとも別の場所にあるのか、まずは絞り込むことが肝心かと思います。

zero-enna
質問者

お礼

回答を頂きありがとうございました.調査の結果,原因はCRCの計算ではないということが分かったので,締め切らせてもらいました. 送信側ではデータ128バイトプラスCRC2バイトの130バイト送信しているのですが,受信側で特定のデータブロックのときのみ129バイトしか受信されていませんでした.なぜかCRCの下位ビットが切れてしまうのです.これはこれで疑問なのですが,この質問とは関係なくなるのでここで終了とさせてもらいます. 私の調査不足が招いたことですが,ご回答を頂きありがとうございました.

その他の回答 (3)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

変数の初期化忘れとかの可能性が高いように見受けられます。 C/C++の規格上は、宣言だけして値を代入していない変数には、 どんな数値が格納されているのかは不定です。 そのため、変数を使用する前には何らかの値を代入して必ず初期化しなければなりません。 ところが、 VisualC++ は、デバッグモードでは、明示的に初期化していない変数も0で初期化してくれます。 そのため、初期化していない変数に0が入ってるつもりで処理してたりすると、 デバッグモードではちゃんと動くがリリースモードではちゃんと動かない、 ということになります。

zero-enna
質問者

お礼

回答を頂きありがとうございました.調査の結果,原因はCRCの計算ではないということが分かったので,締め切らせてもらいました. 送信側ではデータ128バイトプラスCRC2バイトの130バイト送信しているのですが,受信側で特定のデータブロックのときのみ129バイトしか受信されていませんでした.なぜかCRCの下位ビットが切れてしまうのです.これはこれで疑問なのですが,この質問とは関係なくなるのでここで終了とさせてもらいます. 私の調査不足が招いたことですが,ご回答を頂きありがとうございました.

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

>どなたかアドバイスを頂ければと思います。よろしくお願いします。 ソースを見ないことにはなんともいえません。 通常、デバッグで動いてリリースで動かないのは、プログラムにバグがあるからです。コンパイラの問題であることは非常に稀です。 仮にコンパイラの問題だとしても、ソースがないことにはなんともいえないのは一緒です。

zero-enna
質問者

補足

vData:CRCを計算する8ビット(unsigned char) vCRC:CRC(unsigned short) 1データブロックは128バイトでそのお尻に2バイトのCRCを連結します. pszBuf:受信バッファ. vData = 0; vCRC = 0; for(int buff_num = 0; buff_num < 128; buff_num++){ vData = pszBuf[buff_num]; for(loop = 0; loop < 8; loop++){ // CRCを1バイト計算 // CRC計算変数がシフトで桁あふれするか確認 if((vCRC & 0x8000) != 0){ // 桁あふれあり vCRC = vCRC << 1; // CRC計算変数1ビットシフト vCRC = vCRC ^ 0x1021; // 生成多項式のXOR }else{ // 桁あふれなし vCRC = vCRC << 1; // CRC計算変数1ビットシフト } // データ変数がシフトで桁あふれするか確認 if((vData & 0x80) != 0){ // 桁あふれあり vData = vData << 1; // データ変数1ビットシフト vCRC = vCRC ^ 0x0001; // CRC計算変数に1XOR }else{ // 桁あふれなし vData = vData << 1; // データ変数1ビットシフト } } } また,特定のファイルを転送しようとしたときのみこの症状が出ます.そしていつも同じ場所でとまってしまいます.(例:13,447バイトのJPEGファイルを転送しようとすると,2816バイトまでしか転送されない)デバッグではその場所でエラーが出たりすることはありませんでした.

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.1

 一般的にはデバッグで動作OK,リリースでNGとなるのは潜在的なバグがあります。デバッグ版ではたまたま動いているように見えているだけです。  例えば初期化していない変数を使っているとか,宣言した配列をはみ出して読み書きしているとか考えられます。  また,XORの計算に不安があるのであれば,ソースの一部でも抜粋して補足資料として付けてもらえば詳細なアドバイスがもらえると思います。  既に行っているかもしれませんが,コンパイラのワーニング(警告)レベルをあげて,コンパイラからワーニングを出させ,コードの問題点がないか確認します。基本はワーニング0件を目指します。

zero-enna
質問者

お礼

回答を頂きありがとうございました.調査の結果,原因はCRCの計算ではないということが分かったので,締め切らせてもらいました. 送信側ではデータ128バイトプラスCRC2バイトの130バイト送信しているのですが,受信側で特定のデータブロックのときのみ129バイトしか受信されていませんでした.なぜかCRCの下位ビットが切れてしまうのです.これはこれで疑問なのですが,この質問とは関係なくなるのでここで終了とさせてもらいます. 私の調査不足が招いたことですが,ご回答を頂きありがとうございました.

zero-enna
質問者

補足

vData:CRCを計算する8ビット(unsigned char) vCRC:CRC(unsigned short) 1データブロックは128バイトでそのお尻に2バイトのCRCを連結します. pszBuf:受信バッファ. vData = 0; vCRC = 0; for(int buff_num = 0; buff_num < 128; buff_num++){ vData = pszBuf[buff_num]; for(loop = 0; loop < 8; loop++){ // CRCを1バイト計算 // CRC計算変数がシフトで桁あふれするか確認 if((vCRC & 0x8000) != 0){ // 桁あふれあり vCRC = vCRC << 1; // CRC計算変数1ビットシフト vCRC = vCRC ^ 0x1021; // 生成多項式のXOR }else{ // 桁あふれなし vCRC = vCRC << 1; // CRC計算変数1ビットシフト } // データ変数がシフトで桁あふれするか確認 if((vData & 0x80) != 0){ // 桁あふれあり vData = vData << 1; // データ変数1ビットシフト vCRC = vCRC ^ 0x0001; // CRC計算変数に1XOR }else{ // 桁あふれなし vData = vData << 1; // データ変数1ビットシフト } } } また,特定のファイルを転送しようとしたときのみこの症状が出ます.そしていつも同じ場所でとまってしまいます.(例:13,447バイトのJPEGファイルを転送しようとすると,2816バイトまでしか転送されない)デバッグではその場所でエラーが出たりすることはありませんでした.

関連するQ&A

  • CRC16計算について

    CRC16のプログラムを作ったのでデバッグしていて気付いた事なのですが (産業装置で使うMODBUS-RTUのソフト) CRC16 x16+x15+x2+1 生成多項式 0xA001 CRC16でCRCを含めたデータを再CRCするとゼロになると言われておりますが そうならないのですが何故でしょう? もちろん、自分の作ったソフトが信用できないので他ソフトで検証 具体例 ベクターにあるCRC16の計算ソフト - CRC16.exe http://blog.goo.ne.jp/masaki_goo_2006/e/50b20edb79f60964faeaefe6fa064469 これに文字列"ABCD" [0x4142,0x4344]を入れて計算実行 出力結果  初期値:0xFFFF、出力XOR:0xFFFF、出力結果、右送り0x0F85 この出力を最初の文字列に追加する 0x4142,0x4344,0x0F85 結果は0xc7e6 となってゼロになりません やりかたが違うのでしょうか? 尚、私の作ったプログラムと上記ソフトの結果が同じです また、ネット上にある同様な他ソフトでも同じ結果でした (もちろんCRC計算条件が同じ物) 尚、上記ソフトで 初期値:0x0000、出力XOR:0x0000、左送り:9AA8 この場合のみCRC追加しての再CRCはゼロになりました ゼロになる場合とならない場合があるのでしょうか?

  • CRCの使い方、mysqldumpについて

    先日、社内DBのcronによる定期バックアップのデータが圧縮により破損したらしく、 顧客データを数日前まで戻さなくてはいけなくなりました。 私の所属している部署ではなかったのですが、同様の問題が発生するかもしれないので、 cronで毎日取っているバックアップデータをチェックするなどの方法を求められました。 ただ、私は経験もないため何をどうすればいいのか分かりません。 CRCでチェックすればいいのでは?と言われたのでCRCについて調べたのですが、 ググってみたのですが、CRCエラーの対処法や、CRCの解説がほとんどで、実際の使い方が見つかりません。 どのようにすれば、CRCでチェックサムを付加することができるのでしょうか? 付加したデータは専用の通信をするのでしょうか? scpやrsyncのようなコマンドがあると思っていたのですが、見つかりません… CRCでやりたいことは以下になります。 「DBサーバ 」と「DBバックアップサーバ」があり、 OSは「DBサーバ」が CentOS release 6.3 (Final) で、 「DBバックアップサーバ」が CentOS release 6.5 (Final) です。 「DBバックアップサーバ」上で mysqldump {「DBサーバ 」} {DB名} > {hoge.sql} をcronで実行しています。 この {hoge.sql} が正常か異常かを確かめたいのです。 サーバ上で障害等ない場合、mysqldumpで異常なデータが出力されたりすることはあるのでしょうか? HD上の空きには余裕がある状態で、他に特にサーバ上での問題もない場合、圧縮でデータが破損することはあるのでしょうか? CRCでできないのであれば、他にどのような手法があるのでしょうか? 完全に丸投げの質問で申し訳ないのですが、どうぞご教示をお願いいたします。

  • CRCエラー

    クレードルを利用して3.5インチHDDにデータを保存していたのですが、コピー前は問題のなかったrarファイル多数にCRCエラーが生じるようになりました。 複数のPCからSATA、USBで接続し解凍を試みましたがどの機もエラー。 転送時に問題が生じたのか、HDD本体が障害を抱えたのか、そのほかに原因があるのか、問題解決のヒントを頂ければと重います。 因みに不良セクタは検出されませんでした。

  • VC++でDeugモードOKで、Releaseモードのみでエラーが出る?

    マイクロソフトのVisualC++で テキストデータを処理するプログラミングしています。 (MFCは使っていません。) 使用してたプログラムの 一部の変数をクラス化しました。 数多くのエラーをかいくぐり、 Debugモードでは、 目的の演算を実行することができるようになりました。 ところが、 このプロジェクトをReleaseモードでビルド実行すると、 「trans1.exe の 0x0040d052 でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x2eb11a94 に書き込み中にアクセス違反が発生しました。」 というエラーが出て止まってしまいます。 プロジェクトのプロパティ設定で、 ヒープ領域をDebugモードと 同じにしてみたりしたのですが、 状況は改善されません。 メモリの問題のような気がして、 配列の大きさ等をチェックしましたが、 問題なしでした。 プログラムを他の人が使えるように するためには、 Releaseモードが必要なので困っています。 どなたか、アドバイスかご教示お願いします。 デバッグ方法を教えて頂いても大変助かります。 よろしくお願いします。

  • エラーの原因が・・・

    ただいまVisualC++を使ってプログラミング中なのですが、エラーの原因が分からず困っています。 デバッグ開始(緑色のボタンをクリック)して以下のような状態になります。 エラーメッセージは「test.exe の 0x1029e9ee でハンドルされていない例外が発生しました: 0xC0000005: 場所 0xcdcdcdcd を読み込み中にアクセス違反が発生しました。」です。 エラーが出ているのは逆アセンブルのところで、main関数の終わり(}のところ)からステップインをしていった途中の「movsx ecx,byte ptr [eax]」の文でエラーが発生していることが分かりました。 この文はソースのどの部分に対応しているか分からず、困っています。 いつもは配列の添字が要素数を超えていたりするのですが、エラーの場所が場所なので原因が分かりません。 ソースコードは分割が多く、どこを載せていいのかさっぱりです。 情報が少ないので、必要な情報などありましたら言ってください。

  • VS2008 C++ リリースモードでエラー

    表題の環境でMFCベースのプログラムを開発しています。 リリースモードで実行を試したところ、同じようなタイミングで強制終了が発生します。 (おそらく、自前のDLL内で落ちている?) デバッグモードのEXEを直接起動しても、強制終了が発生します。 りかし、VSからリリースモード(当然、デバッグモードも)の実行を行うと、エラーが発生しません。 VSから実行する場合、参照するDLLはVSを使用しない場合とは違うDLLを参照するのでしょうか。 その他、このような状況での対処方法について、アドバイスをいただけませんでしょうか。

  • OS X用 RealPlayer 10ダウンロードエラー

    こんばんは。OS X 10.1.5を利用しています。 Realのホームページから「OS X用 RealPlayer 10」をダウンロードし、インストールしようとした所、以下のエラーが出ます。 どうすれば正常にインストールできるでしょうか?教えて下さい。 イメージ名:RealPlayer10GOLD.dmg イメージフォーマット:UDIF読み込み専用 チェックサム:CRC32 SBD98B816無効 RealPlayer10GOLD.dmgを検証できません。 よろしくお願いします。

    • ベストアンサー
    • Mac
  • BLOBって何でしょうか? BLOBエラー

    はじめまして Windows VC++ .NETでプログラミングをしております。 本日デバッグをしていたところある条件下で以下のようなエラーが発生しました。 ******************************************************************** 0x77e338b2 で初回の例外が発生しました : Microsoft C++ exception: Magick::ErrorBlob @ 0x01f25224。 ******************************************************************** 違いといえばプログラム本体に食わせる設定ファイル内に改行があるかどうかくらいです。 このようなエラーは出たことがありませんので解決のアドバイスをいただければと思います。(サイト上にもほとんど情報がありませんでした。) よろしくお願いいたしますm(_ _)m

  • エラーDlg「An invalid argument was encountered」について

    はじめまして。 表題のエラーメッセージについて質問させてください。 VC++ 2005 MFC で開発をしております。 OS Windouws 2000 処理としましては複数のスレッドを走らせて Cimageを作成して描画するといった仕様です。 VCより実行後、 デバッグモードの場合、 エラーDlg「~.exe によってブレークポイントが発生しました」 が表示され、継続ボタンを押下すると エラーDlg「An invalid argument was encountered」 が表示されます。 リリースモードの場合 エラーDlg「An invalid argument was encountered」 が表示されます。 両者とも (デバッグモードの場合、警告無視)しばらくすると エラーDLGは発生しなくなります。 本現象はどのような場合に発生するのでしょうか? また解決の糸口になるような情報がございましたら 教えていただきたく思います。 同件と思われますが、 Windows XP の場合、 配布パッケージ形式(リリース、デバッグ版ともに)で実行しますと、 問題なく動作します。 Windows 2000の場合、 配布パッケージ形式(リリース版)で実行しますと エラーDlg「An invalid argument was encountered」 が表示され、OKボタン押下で継続して処理が続くのですが、 「エラーが発生したため、~.exeを終了します。プログラムをもう一度開始する必要があります。 エラー ログを作成しています。」 と表示され、アプリが落ちます。 配布パッケージ形式(デバッグ版)で実行しますと 問題なく実行できます。 ※補足 開発環境(VS 2005)が入ってるPC(Windows 2000)の場合は エラーDlg「An invalid argument was encountered」は表示されますが、 その後、正常に動作します。 Windows 2000の場合に本エラーが発生するようです。 かなりはまっています。 どなたかお詳しい方がおりましたら ご教授お願い致します。 以上になります。 よろしくお願い致します。

  • リリース版にすると例外エラーが発生する

    同じような質問がないか検索したのですが、ないようなので質問させてもらいます。 Visual C++2010 Expressを使ってプログラムを書いている、アプリケーション作成初心者です。 デバッグが一区切りしたため、リリース版でビルドし実行したところ、コンストラクターの 内部で、下記のエラーが発生しました。 ”アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。” ”使用されたパラメータが有効ではありません” デバッグ版では、発生しません。 エラーが発生するコードは、以下の行です。 InitializeComponent(); Blank = gcnew Bitmap("Blank.png"); この、Bitmapをgcnewする行で、上記のエラーウィンドウが表示されます。 ビルドパラメータは、リンカ入力の追加の依存ファイルに"Wsock32.lib"が指定されています。 他は、変更していません。 メモリの問題でしょうか? よろしくお願い致します。