Help needed with SEH exception handler (not really Win32 specific)

Hans Boehm Hans.Boehm@hp.com
Fri Mar 14 05:39:00 GMT 2003


In the gc case it would probably be sufficient to set a per thread
flag in the handler, and then have the wrapper check that flag.  
That's admittedly dodging the issue rather than solving it.

In the exception case, could you change the context to restart someplace
that does the longjmp?  I haven't thought this through ...

Hans

On Fri, 14 Mar 2003, Ranjit Mathew wrote:

> Hi,
> 
>     I'm stuck with what is essentially the same problem in trying 
> to fix the SEH issues in both the GC as well as the libgcj 
> win32_exception_handler( ) method, and I hope someone can shed
> some insights into it - how do I restart execution after a fault in 
> a robust manner, while still being able to indicate to the OS
> that I have taken care of the error? I'll try to clarify this
> problem below, but before I do, I must note that the setjmp/longjmp
> based approach that is taken in this mail:
> 
>     http://sources.redhat.com/ml/cygwin/2002-08/msg01598.html
> 
> suffers from the same problem as our current win32_exception_handler( )
> in that execution "sneaks out" from the handler and the OS is 
> not returned a value indicating whether the handler was able to
> resolve the error or not.
> 
> The simplest case is trying to emulate the following construct:
> 
>     __try {
>       ...
>       return 0;     /* Normal return value */
>     } __except {
>       return 666;   /* Abnormal return value */
>     }
> 
> As might be recalled, I could install/uninstall my own handler, say,
> snafu_handler( ) using simple inline assembly in GCC. So the handler
> gets control when, say, an access violation (SEGV) happens.
> 
> The problem is that the handler must arrange for the *original method*
> to return "666" and yet be able to return a value to the OS
> indicating that the exception has been taken care of (by returning
> "ExceptionContinueExecution", which restarts the execution at the
> instruction that caused the fault).
> 
> What I *do* have is a "struct _CONTEXT" that is passed to the
> handler, which represents a snapshot of all the registers at the time
> of the fault - if I modify this context, the changes are reflected
> back in the thread when execution is restarted at the "faulty"
> instruction (the PC itself can be changed to point to a different
> location).
> 
> My first approach was to try to set the PC to a label in the function,
> but this is not at all allowed by GCC.
> 
> My second approach was to try to set the PC to the address of a
> "trampoline" dummy function that merely returns the desired 
> value. However, this dummy function's prologue/epilogue are
> unnecessarily executed and (more importantly) the epilogue in 
> the original function is skipped, so the stack does not have 
> consistent call frames.
> 
> The situation gets more complicated (as I see it) for the
> general exception handler function (win32_exception_handler( ))
> and the MAKE_THROW_FRAME approach in the libgcj Linux
> code would not (again, as I see it) work.
> 
> Is there something blindingly obvious that I'm missing? Have
> any of you ever faced such a situation before?
> 
> And much thanks in advance if you're able to help me out of
> this. :-)
> 
> Ranjit.
> 
> --
> Ranjit Mathew               Email: rmathew AT hotmail DOT com
> 
> Bangalore, INDIA.           Web: http://ranjitmathew.tripod.com/
> 

-- 
Hans Boehm
(hboehm@hpl.hp.com)



More information about the Java mailing list