MacOSXにVorbisOggファイルをロードする際に不思議なバグがありました。最初のファイルは正しくロードされ、2番目のファイルはファイルが破損していることを示すコードでクラッシュします。同じ正確なファイルを2回ロードしても、同じことが起こります。
Vorbis内での長時間の詳細なデバッグの結果、バグの原因は、システム関数 "pow"(の2倍)が完全に有効な入力に対して(nan)を返すことであり、これは(ov_readの2回目の呼び出しでのみ発生する)ことがわかりました。 )、最初の呼び出しで、「pow」に渡された同じ正確な値が有効な結果を返します。
8時間後、Intelx87のドキュメントをたくさん読んで問題が見つかりました。簡単に言うと、このアセンブリコードを使用する関数「vorbis_ftoi」がvorbisの奥深くにあります。
__asm__("fistl %0": "=m"(i) : "t"(f));
これは、IntelFPUスタックをプッシュしてポップする必要があります。ただし、LLVMでは次のコードが生成されます。
fld QWORD PTR [ebp-0x20]
fist DWORD PTR [ebp-0x14]
これはスタックをプッシュしますが、FPUスタックオーバーフローを引き起こすことはありません。そしてそれは明らかにLLVMのバグです
GCCによって生成される適切なコードは次のようになります。
fld QWORD PTR [ebp-0x20]
fist DWORD PTR [ebp-0xc]
fstp st(0) // pops off the stack
私はこれについていくつかのゴミ(x87命令セットとレジスター)を学ぶ私のブライアンの1日半と数バイトを無駄にしたので、私はそれを共有したいと思います。
オーデイ