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.orghttp://q12.org/mailman/listinfo/ode