Exceptions in native code

Jorn Vernee jorn.vernee at oracle.com
Wed Apr 30 13:19:30 UTC 2025


For downcalls, native exceptions currently end up in the JVM's signal 
handler, which then turns them into those 'Internal Error's. 
Theoretically it seems possible to install some kind of NativeException 
(a Java type) at that point and then return back to Java just after the 
downcall. The user could then catch the exception and choose how to 
handle it. This could work for JNI native methods as well I think, as 
long as we record some 'exception continuation point' from which to 
continue executing when an exception is encountered.

The bigger issue for me is: how should we then surface platform specific 
information about the native exception. For example, on Windows the 
exception info takes the form of an EXCEPTION_POINTERS struct [1]. How 
should this be surfaced in the API, so that the user has access to the 
info inside, and can use it to handle the exception? Is it acceptable to 
have a public WindowsException type in the JDK that exposes an API to 
retrieve data from this struct? (in which case the user could do an 
instanceof check on the NativeException, and then cast to the specific 
type). But then, what happens if the contents of EXCEPTION_POINTERS 
changes on a particular Windows version? Even if we just expose the 
exception code (an int), we would still need to communicate the 
exception type to the user somehow, so they know how the code should be 
interpreted. Then repeat this for all types of native exceptions (or at 
least a subset we want to support).

Though, I think the issue of re-throwing a native exception thrown by a 
downcall as a Java exception, is simpler than having better handling for 
Java exceptions thrown during upcalls, because the latter requires you 
to invent a way to unwind an arbitrary native stack, as Maurizio says.

Jorn

[1]: 
https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_pointers

On 28-4-2025 15:04, Maurizio Cimadamore wrote:
> Hi,
> We have explored the topic of exceptions, mostly from the point of 
> view of a Java exception while executing an upcall from native code. 
> At the time being the Linker doesn't handle native exceptions (as you 
> have seen).  What you want to happen here is to unwind the stack in 
> the same way as the C code would have done it (e.g. by letting other 
> handlers, if present, to execute) -- then, when back to Java, rethrow 
> as some kind of Java exception. What you don't want to happen is to 
> stop native execution "there and then" and jump back to Java (e.g. pop 
> all native frame) -- as that might leave the native library in an 
> inconsistent state.
>
> While it's not impossible to better support for native exceptions in 
> downcalls/upcalls (API-wise, this is rather trivial to do, e.g. with a 
> linker option), such support would have to wrestle with wild platform 
> inconsistencies. For instance, Windows supports so called structured 
> exceptions [1], which provides a standard API for doing stack 
> unwinding. On Linux there's unfortunately no "standard" way for doing 
> this. Libunwind [2] is probably the most portable effort in this 
> direction, but creating adding a dependency between it and the JVM 
> made us nervous back then (and still does).
>
> Maurizio
>
> [1] - 
> https://learn.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-170
> [2] - https://github.com/libunwind/libunwind
>
> On 28/04/2025 13:11, White_145 wrote:
>> Whenever C code uses exceptions (in my case raised by 
>> `RaiseException` (windows) or `_Unwind_RaiseException` (linux)) and 
>> java takes control of the execution, it crashes the VM with an 
>> "Internal Error" message.
>> I'm using bindings for LuaJIT, and it raises exceptions quite a lot 
>> for the purpose of stack unwinding. Most of them are easy to avoid: 
>> errors and yields can be simply wrapped by a C function so that java 
>> doesn't see it, but others, signaling for Out Of Memory, are not so 
>> straightforward.
>> Is there a way to handle (perhaps, convert to a Java Exception?) 
>> these native exceptions before Java crashes the VM, given that the 
>> error code is known? If not, is it planned/possible in the future?
>> I have little experience in this kind of problem: in fact, my only 
>> experience is trying to deal with it, so be free to call out the 
>> wrong terminology and/or approach. I have been searching for a 
>> solution [what seems to be] everywhere, but I haven't found anyone 
>> with the same problem.
>>


More information about the panama-dev mailing list