Hi James,
You always know how to nerd snipe me!
On Thursday, January 27, 2011 06:35:08 pm James Stone wrote:
I have been working on the Neil tracker program
recently,
and hit a weird bug that seems to affect only my
computer! I get a segfault when trying to use fft.h
Not just you. It segfaults for me, too. Ubuntu 10.04 with Core Duo
processor.
With the patch below (to fft.h) I detect that p2r and p2i overrun the
buffer when k==11, j==0, i==0. However, k was supposed to STOP when
it reached 11 = log(2048)/log(2).
My guess is that is that the integer k is promoted to a float and the
comparison is performed. When I replace:
for (k = 0, le = 2; k < log(fftFrameSize)/log(2.); k++) {
with:
long ITERS = log(fftFrameSize)/log(2.0) + 0.5;
for (k = 0, le = 2; k < ITERS; k++) {
...the code doesn't crash on me. Here's a sample program that
illustrates what's happening.
/* BEGIN */
#include <cmath>
#include <iostream>
using namespace std;
#define ITERS (log(2048)/log(2.0))
int main(void)
{
long k;
for( k=0 ; k < ITERS ; ++k ) {
cout << "k = " << k
<< " ITERS = " << ITERS
<< " diff = " << (ITERS - k)
<< endl;
}
return 0;
}
/* END */
Output on my machine:
k = 0 ITERS = 11 diff = 11
k = 1 ITERS = 11 diff = 10
k = 2 ITERS = 11 diff = 9
k = 3 ITERS = 11 diff = 8
k = 4 ITERS = 11 diff = 7
k = 5 ITERS = 11 diff = 6
k = 6 ITERS = 11 diff = 5
k = 7 ITERS = 11 diff = 4
k = 8 ITERS = 11 diff = 3
k = 9 ITERS = 11 diff = 2
k = 10 ITERS = 11 diff = 1
k = 11 ITERS = 11 diff = 4.80518e-16
Thanks,
Gabriel
Here's the testing patch....
--- a/fft.h
+++ b/fft.h
@@ -1,5 +1,7 @@
#define M_PI 3.14159265358979323846
+#include <assert.h>
+
void IFFT(float *fftBuffer, long fftFrameSize, long sign)
/*
FFT routine, (C)1996 S.M.Sprenger. Sign = -1 is FFT, 1 is iFFT
(inverse)
@@ -17,6 +19,7 @@ void IFFT(float *fftBuffer, long fftFrameSize, long
sign)
float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
long i, bitm, j, le, le2, k;
+
for (i = 2; i < 2 * fftFrameSize - 2; i += 2) {
for (bitm = 2, j = 0; bitm < 2 * fftFrameSize; bitm <<= 1) {
if (i & bitm) j++;
@@ -48,6 +51,10 @@ void IFFT(float *fftBuffer, long fftFrameSize, long
sign)
p2r = p1r+le2;
p2i = p2r+1;
for (i = j; i < 2 * fftFrameSize; i += le) {
+ assert(p1r < (fftBuffer + 2 * fftFrameSize));
+ assert(p1i < (fftBuffer + 2 * fftFrameSize));
+ assert(p2r < (fftBuffer + 2 * fftFrameSize));
+ assert(p2i < (fftBuffer + 2 * fftFrameSize));
tr = *p2r * ur - *p2i * ui;
ti = *p2r * ui + *p2i * ur;
*p2r = *p1r - tr;