[ODE] Using exceptions to catch errors

Jon Watte hplus-ode at mindcontrol.org
Thu Aug 12 01:47:39 MST 2004


If error_function is called and throws, then the exit() 
in the scErrorHandler function will not be reached, unless 
your compiler is REALLY FUCKED UP. And it likely isn't.

Are you sure you're catching all exceptions? Perhaps the 
exit that happens is some ODE call you weren't wrapping? 
At times, I find it useful to wrap all of main() in a 
global catch-all:

int main( int argc, char * argv[] ) {
  try {
    all code goes here
  }
  catch( ... ) {
    puts( "this is not good" );
  }
  return 2;
}


-----Original Message-----
From: ode-bounces at q12.org [mailto:ode-bounces at q12.org]On Behalf Of
Shamyl Zakariya
Sent: Wednesday, August 11, 2004 5:09 AM
To: ode at q12.org
Subject: [ODE] Using exceptions to catch errors


All

I've tuned my usage of ODE well enough by this point that it *almost* 
never ends up exploding... but of course, once in a blue moon, now and 
then, it does.

Since the default implementation of the error handler calls abort() or 
error(1) my program, obviously, terminates. To the user it looks like 
it crashed! I'd prefer behavior to be to close the simulation, reset 
everything, and show an alert dialog explaining everything.

I know that in principle I could just remove the exit & abort code from 
ODE, but I'd like to use a standard ODE distribution.

So I thought that what I'd do is register my own error handler and have 
it throw an exception, which would be caught and my program would close 
the simulation and reset ODE.

So, here are my error/debug callback functions, where scError and 
scDebug are just vanilla C++ objects.

	void scErrorHandler(int errnum, const char *msg, va_list ap)
	{
		printMessage( errnum, "PANSISim : ODE Error : ", msg, ap );
		throw scError();
	}

	void scDebugHandler(int errnum, const char *msg, va_list ap)
	{
		printMessage( errnum, "PANSISim : ODE INTERNAL ERROR : ", msg, ap );
		throw scDebug();
	}

They're registered with ODE as such:

	dSetErrorHandler( scErrorHandler );
	dSetDebugHandler( scDebugHandler );

And the relevant part of my stepping function looks like this:

	if ( !_aborted )
	{

		try {

			Element::stepAll();

			dSpaceCollide (_space, (void *) this, &nearCallback);
			dWorldStep( _world, timestep() );
			dJointGroupEmpty( _contactGroup );
		}

		catch ( scError err )
		{
			printf( "SimulationCore::step()\tCaught error. aborting stepper\n" );
			_aborted = true;
		}

		catch( scDebug debug )
		{
			printf( "SimulationCore::step()\tCaught debug. aborting stepper\n" );
			_aborted = true;
		}
				
		if ( _aborted )
		{
			stopPANSI(); 	//synchronously stops AI runtime thread
			reset();		//unloads simulation and closes ODE
		}
	}


So, the trouble as I see it is this: in ODE's error.cpp the function 
dError is defined as such:

extern "C" void dError (int num, const char *msg, ...)
{
   va_list ap;
   va_start (ap,msg);
   if (error_function) error_function (num,msg,ap);
   else printMessage (num,"ODE Error",msg,ap);
   exit (1);
}

Where error_function is called, then printMessage, then exit, is 
called. The oddity here is that even though my error callbacks are 
being called and the exception *is* being thrown, exit() is still being 
called. I would have expected that the throwing/catching of an 
exception would have prevented exit from ever being called. Am I 
misunderstanding exception usage? I used to use them all the time in 
java, but I've never used them much in C++, due to poor support.

If it helps the platform is mac OS 10.3 with gcc 3.3

shamyl zakariya | fodder for aggressive meta-lampoonery

_______________________________________________
ODE mailing list
ODE at q12.org
http://q12.org/mailman/listinfo/ode




More information about the ODE mailing list