2011-10-11 14 views
9

Tôi đã gặp lỗi bí ẩn khi tải các tệp Vorbis Ogg trên Mac OSX. Tệp đầu tiên được tải chính xác, sự cố thứ hai trong một số mã cho biết tệp bị hỏng, điều tương tự xảy ra ngay cả khi tôi tải cùng một tệp chính xác hai lần.Lỗi OSX MAC OSX Intel LLVM (khiến trình tải Vorbis OGG bị lỗi)

Sau nhiều giờ gỡ lỗi sâu bên trong Vorbis, tôi phát hiện ra lỗi do chức năng hệ thống "pow" (công suất kép) trả về (nan) cho đầu vào hoàn toàn hợp lệ và chỉ xảy ra vào giây gọi đến (ov_read), trên lần gọi đầu tiên, các giá trị chính xác được chuyển đến "pow" sẽ trả lại kết quả hợp lệ.

8 giờ sau và rất nhiều tài liệu đọc x87 của Intel tôi đã tìm thấy sự cố. Dài câu chuyện ngắn có một chức năng sâu bên trong vorbis "vorbis_ftoi" sử dụng mã lắp ráp này:

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

Nên đẩy và bật trên ngăn xếp FPU của Intel. Tuy nhiên trên LLVM nó tạo ra mã này:

fld QWORD PTR [ebp-0x20] 
fist DWORD PTR [ebp-0x14] 

Đẩy vào ngăn xếp nhưng không bao giờ bật ra gây tràn FPU. Và đó là rõ ràng là một lỗi trong LLVM

Các mã đúng được tạo ra bởi GCC trông như thế này:

fld QWORD PTR [ebp-0x20] 
fist DWORD PTR [ebp-0xc] 
fstp st(0)  // pops off the stack 

tôi lãng phí một ngày rưỡi và một số byte của brian mình biết một số rác (x87 Instruction Set và Thanh ghi) về điều này, vì vậy tôi mặc dù tôi sẽ chia sẻ nó.

Auday

+2

Nếu bạn cho rằng mình đã tìm thấy lỗi trong mã do Apple cung cấp, bạn nên báo cáo lỗi đó cho Apple: https://bugreport.apple.com/cgi-bin/WebObjects/RadarWeb.woa/wa/signIn –

+0

xong , cảm ơn Ned – Auday

+0

+1 bởi vì tôi đã tìm thấy một lỗi trong mã của họ ngày hôm qua cũng như và cũng báo cáo nó. Ít nhất tôi là một vụ tai nạn biên dịch nên thời gian gỡ lỗi không quá tệ ... –

Trả lời

2

Tuyệt vời! Cảm ơn bạn. Một giải pháp khác là chỉ cần loại bỏ hoàn toàn asm. Đây là một bản vá:

--- lib/os.h 2011-11-13 20:36:24.000000000 -0500 
+++ lib/os.h  2011-11-15 18:45:00.000000000 -0500 
@@ -93,27 +93,16 @@ 
typedef ogg_int16_t vorbis_fpu_control; 

static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){ 
- ogg_int16_t ret; 
- ogg_int16_t temp; 
- __asm__ __volatile__("fnstcw %0\n\t" 
-   "movw %0,%%dx\n\t" 
-   "andw $62463,%%dx\n\t" 
-   "movw %%dx,%1\n\t" 
-   "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx"); 
- *fpu=ret; 
} 

static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){ 
- __asm__ __volatile__("fldcw %0":: "m"(fpu)); 
} 

/* assumes the FPU is in round mode! */ 
static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise, 
               we get extra fst/fld to 
               truncate precision */ 
- int i; 
- __asm__("fistl %0": "=m"(i) : "t"(f)); 
- return(i); 
+ return (int)floor(f+.5); 
} 
#endif /* Special i386 GCC implementation */ 
3

đơn giản vá, đã ảnh hưởng đến chỉ khi biên dịch với 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 

Thật không may, tôi không có đủ uy tín để bỏ phiếu lên OP, nhưng biết rằng tôi m biết ơn cho tìm thấy của bạn. Cảm ơn bạn.

+0

Tôi cũng gặp vấn đề chính xác này và bản sửa lỗi này đã làm việc cho tôi. Cảm ơn! – Tod