我在Mac OSX上加载Vorbis Ogg文件时遇到了一个神秘的错误。第一个文件已正确加载,第二个文件因某些代码崩溃而表明该文件已损坏,即使我两次加载相同的文件也一样。

在Vorbis内部进行了长时间的深入调试之后,我发现该错误是由系统功能“ pow”(双幂)导致的,它返回一个(nan)以获得完全有效的输入,并且仅在对(ov_read ),在第一次调用时,传递给“ pow”的相同精确值会返回有效结果。

8小时后,阅读了许多Intel x87文档,我发现了问题。长话短说,在vorbis“ vorbis_ftoi”内部深处有一个使用此汇编代码的函数:

__asm__("fistl %0": "=m"(i) : "t"(f));


哪个应该推入并弹出Intel FPU Stack。但是,在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指令集和寄存器),因此尽管我会分享它。

Auday

最佳答案

更简单的补丁程序,仅在使用llvm进行编译时才起作用:

--- Xiph\vorbis\os.h    Mon Mar 28 08:42:43 2011
+++ Xiph\vorbis\os.h    Thu Feb 02 14:20:27 2012
@@ -81,7 +81,7 @@


 /* Special i386 GCC implementation */
-#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
+#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__) && !defined(__llvm__)
 #  define VORBIS_FPU_CONTROL
 /* both GCC and MSVC are kinda stupid about rounding/casting to int.
    Because of encapsulation constraints (GCC can't see inside the asm


不幸的是,我没有足够的声誉来投票赞成OP,但是我知道我很感谢你的发现。谢谢。

08-15 23:43