バイトスワップ+CString+ファイルアクセスで最適化をかけて実行すると落ちる – 固定ページ 2 – プログラミング – Home

バイトスワップ+CString+ファイ...
 
通知
すべてクリア

[解決済] バイトスワップ+CString+ファイルアクセスで最適化をかけて実行すると落ちる

固定ページ 2 / 2

isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

もう少し考察してみました。

fname = dpath + dname_l1;
00401F32 lea edx,[esp+10h]
00401F36 push edx
00401F37 lea eax,[esp+0Ch]
00401F3B push eax
00401F3C lea ecx,[esp+1Ch]
00401F40 push ecx
00401F41 call ATL::operator+ (401D30h)
00401F46 add esp,0Ch
00401F49 push eax
00401F4A lea ecx,[esp+8]
00401F4E mov byte ptr [esp+34h],5
00401F53 call ATL::CSimpleStringT<char,0>::operator= (401B80h)
00401F58 mov eax,dword ptr [esp+14h]
00401F5C add eax,0FFFFFFF0h
00401F5F mov byte ptr [esp+30h],4
00401F64 lea edx,[eax+0Ch]
00401F67 or ecx,0FFFFFFFFh
00401F6A lock xadd dword ptr [edx],ecx
00401F6E dec ecx
00401F6F test ecx,ecx
00401F71 jg CTestDlg3Dlg::OnBnClickedButton1+0EBh (401F7Bh)
00401F73 mov ecx,dword ptr [eax]
00401F75 mov edx,dword ptr [ecx]
00401F77 push eax
00401F78 call dword ptr [edx+4]
00401F7B push esi

fsize = _byteswap_ulong(0xFFFFFFF0);
00401F7C mov esi,0FFFFFFF0h // (1) esi = 0x0fffffff0

file.Write(&fsize, sizeof(fsize));
00401F81 push 4
00401F83 lea eax,[esp+8]
00401F87 bswap esi // (2) ここでesi=0xf0ffffffになる。
00401F89 push eax
00401F8A lea ecx,[esp+24h]
00401F8E mov dword ptr [esp+0Ch],esi
00401F92 call CFile::Write (41D918h)

fname = dpath + dname_l2;
00401F97 lea ecx,[esp+10h]
00401F9B push ecx
00401F9C lea edx,[esp+10h]
00401FA0 push edx
00401FA1 lea eax,[esp+20h]
00401FA5 push eax
00401FA6 call ATL::operator+ (401D30h)
00401FAB add esp,0Ch
00401FAE push eax
00401FAF lea ecx,[esp+0Ch]
00401FB3 mov byte ptr [esp+38h],6
00401FB8 call ATL::CSimpleStringT<char,0>::operator= (401B80h)
00401FBD mov eax,dword ptr [esp+18h]
00401FC1 add eax,esi // (3) 本来は add eax,0FFFFFFF0h とすべきだが、
// esiが0x0fffffff0のままだと思ってesiを使い回して
しまった?
00401FC3 mov byte ptr [esp+34h],4
00401FC8 lea ecx,[eax+0Ch]
00401FCB or edx,0FFFFFFFFh
00401FCE lock xadd dword ptr [ecx],edx
00401FD2 dec edx
00401FD3 test edx,edx
00401FD5 jg CTestDlg3Dlg::OnBnClickedButton1+14Fh (401FDFh)
00401FD7 mov ecx,dword ptr [eax]
00401FD9 mov edx,dword ptr [ecx]
00401FDB push eax
00401FDC call dword ptr [edx+4]

今回はたまたま、_byteswap_ulong(0xFFFFFFF0); で 0xfffffff0 という値が
使用され、それとは無関係な CString::operator= でも 0xfffffff0 という
値を使用するため、それらを最適化しようとして間違った最適化がされて
しまったと考えられます。

試しに _byteswap_ulong() に0xfffffff0以外の値を与えると違ったアセンブリコード
が生成され、落ちずに正常に動きました。


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

誤記訂正
(誤)それとは無関係な CString::operator= でも 0xfffffff0 という
値を使用するため、
(正)それとは無関係な fname = dpath + dname_l2; でも 0xfffffff0 という
値を使用するため、


返信引用
TN
 TN
(@TN)
ゲスト
結合: 15年前
投稿: 8
Topic starter  

isshiさん解説ありがとうございます。
やはりコンパイラのバグでしたか・・・

今回の対応としては固定値の_byteswap_ulong(0xFFFFFFF0)を行わず
0xF0FFFFFFの代入に変更する事で現象を回避をする事が出来ました。

上記テストプログラムを変更して0xFFFFFFF0の値を変数に入れて
data = 0xFFFFFFF0;
fsize = _byteswap_ulong(data);
として呼び出しても現象が発生してしまう為
byteswap_ulongに0xFFFFFFF0の値が入るかもしれない処理の時は
下記の様に条件式で固定値の代入して回避しないと危ない様です。
if(data==0xFFFFFFF0) fsize = 0xF0FFFFFF;
else fsize = _byteswap_ulong(data);

開発環境が.net2003の方は_byteswap_ulongの扱いに注意が必要のようです。
同現象は.net2005/2008では発生しない様ですので修正済みの不具合のようです。

以上で問題解決とします。
皆さんありがとうございました。


返信引用
固定ページ 2 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました