JACK Floating Point Exception/ Divide by Zero Error

Index

Update - This issue has been fixed in JACK 0.103.0

Some JACK users may have noticed that jackd versions from 0.99.37 up to 0.102.x occasionally die with a floating point exception which shows up as a divide trap error in /var/log/syslog. It affects x86 and x86_64 (and possibly others). The code which causes the problem has been removed from JACK 0.103.0, so it doesn't affect later versions.

Basically the problem is a divide by zero error that kills jackd at seemingly random times. It occurs in the "post xrun-handling" section in jackd/engine.c:
		/* post xrun-handling */
		
		jack_nframes_t period_size_guess = 
			engine->control->current_time.frame_rate * 
			   ((timer->next_wakeup - timer->current_wakeup) / 1000000.0);

		timer->frames += 
			((engine->driver->last_wait_ust - 
			 engine->control->frame_timer.next_wakeup) / 
			period_size_guess) * 
			period_size_guess;
Unfortunately period_size_guess always evaluates to zero, so timer->frames ends up having (somevalue/0.0)*0.0 added to it. This usually also evaluates to zero, so most of the time it doesn't have a visible effect, but every once in a while it produces a floating point exception. On systems using multiple sound cards for high channel counts this is likely to happen often enough to be a serious problem.

It is caused by the (incorrect) implicit cast to a float when dividing by 1000000.0. The expression only works if the cast is to a double. This can be done very simply by changing the type declaration of period_size_guess from jack_nframes_t to double, which fixes the problem on both x86 and x86_64. Here's the patch for JACK 0.102.20 (on earlier versions it may have to be applied manually due to different line numbers in jackd/engine.c):
diff -uprN j-0.102.20/jackd/engine.c j2-0.102.20/jackd/engine.c
--- j-0.102.20/jackd/engine.c	2006-08-01 04:26:36.000000000 +0100
+++ j2-0.102.20/jackd/engine.c	2006-12-31 01:03:45.000000000 +0000
@@ -2065,7 +2065,7 @@ jack_run_cycle (jack_engine_t *engine, j
 
 		/* post xrun-handling */
 		
-		jack_nframes_t period_size_guess = 
+		double period_size_guess = 
 			engine->control->current_time.frame_rate * 
 			   ((timer->next_wakeup - timer->current_wakeup) / 1000000.0);


Update - This issue has been fixed in JACK 0.103.0

Index    Contact

Last updated February 24 2007