more on exceptions; new handler

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

more on exceptions; new handler

John W. Eaton-6
Currently, I've defined macros in libcruft/misc/quit.h so that our new
interrupt handling scheme can work with or without exceptions.  But
does this really make sense?  Should we just start using exceptions?

Another change related to exceptions is to do away with the
new_handler that is defined in src/sighandlers.cc (even though it is
not really a signal handler, that's where it is defined).

Instead, we could add a

  catch (bad_alloc) { ... }

block to the main loop in src/toplev.cc so that any bad allocation
ends up back at the top.  Now, does this mean that we will have to
have the same kind of nesting for bad_alloc around foreign code to
protect us if that code is not compiled with exceptions enabled?  It
seems that the answer to that should be yes (and that's what a quick
test just showed).

jwe


Reply | Threaded
Open this post in threaded view
|

Re: more on exceptions; new handler

Paul Kienzle-2
On Thu, Nov 14, 2002 at 09:50:50PM -0600, John W. Eaton wrote:
> Currently, I've defined macros in libcruft/misc/quit.h so that our new
> interrupt handling scheme can work with or without exceptions.  But
> does this really make sense?  Should we just start using exceptions?

We are at this point very dependent on a standard C++ compiler, so assuming
exceptions is not going to cost us anything in terms of portability.  

To be sure that this is the case, I would like to see your except.cc
extended to handle all the cases (fortran code, callbacks, dynamic loading)
so that we can see how well it does (or does not) work on various
platforms.  I'm too tired to do anything about it tonight though.

BTW, with C++ exceptions I presume the unwind_protect class is now
different?  Now you can define unwind_protect as a local variable which
does the unwind operation when it is destructed rather than performing an
unwind stack walk after a long jump.  At least, you can if C++ guarantees
that the destructor is called immediately when the variable goes out of
scope.  Is this any faster than what we have currently?  Or is it just
different.

This leads to another question, which is whether or not it is feasible
to implement evalin, which allows a function to evaluate a variable in
the caller's environment.  Not that I particularly need this feature.

Paul Kienzle
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: more on exceptions; new handler

Paul Kienzle-2
On Fri, Nov 15, 2002 at 01:22:31AM -0500, Paul Kienzle wrote:

> On Thu, Nov 14, 2002 at 09:50:50PM -0600, John W. Eaton wrote:
> > Currently, I've defined macros in libcruft/misc/quit.h so that our new
> > interrupt handling scheme can work with or without exceptions.  But
> > does this really make sense?  Should we just start using exceptions?
>
> We are at this point very dependent on a standard C++ compiler, so assuming
> exceptions is not going to cost us anything in terms of portability.  
>
> To be sure that this is the case, I would like to see your except.cc
> extended to handle all the cases (fortran code, callbacks, dynamic loading)
> so that we can see how well it does (or does not) work on various
> platforms.  I'm too tired to do anything about it tonight though.
Okay, I played with exceptions some more.  The attached except.cc does
work rather than sleep each iteration so you can see that pressing
Ctrl-C does not actually get you to the next iteration any faster.  Sleep
returns immediately after a signal even if the allotted time has not
passed.

I tried throwing an exception directly from the signal handler but that
didn't work.  So it looks like we will indeed have to use this screwy
system of wrapping any computationally intensive code (even C++ code!!)
in the setjmp/longjmp equivalent of try/catch.  How about a START_OP
macro to push a new jump buffer, and END_OP to pop it.  No resource
allocation is allowed between START_OP and END_OP otherwise we would
need to parameterize the START_OP with clean up code.

I still don't know what happens if you throw an exception from a callback
through Fortran code which was not compiled with -fexceptions.

Paul Kienzle
[hidden email]

except.cc (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: more on exceptions; new handler

John W. Eaton-6
In reply to this post by Paul Kienzle-2
On 15-Nov-2002, Paul Kienzle <[hidden email]> wrote:

| We are at this point very dependent on a standard C++ compiler, so assuming
| exceptions is not going to cost us anything in terms of portability.  

OK.

| To be sure that this is the case, I would like to see your except.cc
| extended to handle all the cases (fortran code, callbacks, dynamic loading)
| so that we can see how well it does (or does not) work on various
| platforms.  I'm too tired to do anything about it tonight though.

I can do that if you think it would be useful.  I've also been adding
these features to Octave itself now, but it would be nice to have a
simpler example.  In the process though, I think I'll just clean up
except.cc to not have a #define for the non-exceptions style.
Otherwise, it is too confusing, and we already know that the other way
works (as best it can).

| BTW, with C++ exceptions I presume the unwind_protect class is now
| different?

Not yet, but it could (and probably should) be.

| Now you can define unwind_protect as a local variable which
| does the unwind operation when it is destructed rather than performing an
| unwind stack walk after a long jump.  At least, you can if C++ guarantees
| that the destructor is called immediately when the variable goes out of
| scope.

It should be, I think.

| Is this any faster than what we have currently?  Or is it just
| different.

I'm not sure whether it would be faster, but I think it might be since
Octave's unwind_protect class uses a string compare to find the frame
boundary.  In any case, it might be a bit cleaner.  We could eliminate
calls to unwind_protect::run() and unwind_protect::run_frame() since
that would be handled automatically by destructors when the objects go
out of scope.

| This leads to another question, which is whether or not it is feasible
| to implement evalin, which allows a function to evaluate a variable in
| the caller's environment.  Not that I particularly need this feature.

Yes, I think we can implement evalin.  I think that was already
possible, even without using C++ exception handling?

jwe


Reply | Threaded
Open this post in threaded view
|

Re: more on exceptions; new handler

John W. Eaton-6
In reply to this post by Paul Kienzle-2
On 15-Nov-2002, Paul Kienzle <[hidden email]> wrote:

| Okay, I played with exceptions some more.  The attached except.cc does
| work rather than sleep each iteration so you can see that pressing
| Ctrl-C does not actually get you to the next iteration any faster.  Sleep
| returns immediately after a signal even if the allotted time has not
| passed.

OK.

| I tried throwing an exception directly from the signal handler but that
| didn't work.  So it looks like we will indeed have to use this screwy
| system of wrapping any computationally intensive code (even C++ code!!)
| in the setjmp/longjmp equivalent of try/catch.  How about a START_OP
| macro to push a new jump buffer, and END_OP to pop it.

Sure, I think that's what I already have in the current F77_XFCN macro
in Octave itself.

| No resource
| allocation is allowed between START_OP and END_OP otherwise we would
| need to parameterize the START_OP with clean up code.

Right, that's the current assumption -- any allocations that happen
inside an F77_XFCN call (in Octave) are handled in some other way.
Currently, they can only happen in C++ code called from the Fortran,
and those are protected.  But we could have some way to specify a
clean up function too.

| I still don't know what happens if you throw an exception from a callback
| through Fortran code which was not compiled with -fexceptions.

You crash with a call to abort(), I think.  That's what happened for my
bad_alloc throws before I protected them with a catch block in the
callbacks.

So, give me an hour or so to update the simple except.cc to
demonstrate all these features in a simpler form than all of Octave.
I'll post to the list when I have it working.

jwe


Reply | Threaded
Open this post in threaded view
|

Re: more on exceptions; new handler

Paul Kienzle-2
In reply to this post by John W. Eaton-6
On Fri, Nov 15, 2002 at 09:23:12AM -0600, John W. Eaton wrote:
> | This leads to another question, which is whether or not it is feasible
> | to implement evalin, which allows a function to evaluate a variable in
> | the caller's environment.  Not that I particularly need this feature.
>
> Yes, I think we can implement evalin.  I think that was already
> possible, even without using C++ exception handling?

I didn't see a way of retrieving the symbol table of the caller.  It is
in the unwind stack as defined in ov-usr-fcn.cc:

        unwind_protect_ptr (curr_sym_tab);

but unless I want to walk the unwind stack looking for it, the value is
unavailable:

        curr_sym_tab = sym_tab;

evalin("base") is possible since that is just top_level_sym_tab, but
not evalin("caller").

- Paul