[Gc] Can sigaltstack be used in a GC registered thread?
aph at redhat.com
Tue May 22 08:56:10 PDT 2012
On 05/21/2012 07:59 PM, Boehm, Hans wrote:
>> From: Andrew Haley
>> On 05/21/2012 04:27 PM, Boehm, Hans wrote:
>>> The core issue here is that stack overflow signals are essentially
>>> asynchronous. As far as the programmer is concerned, they can occur
>>> anywhere. Worse yet, they may occur at a "point in the code" that
>>> doesn't really exist, because the compiler has transformed the code.
>>> That means invariants may be arbitrarily broken, locks may be held,
>>> etc. Posix doesn't, and can't, guarantee that longjmping out of
>>> such a signal handler is safe. In some cases it may work, but its
>>> hard to guarantee correctness, GC or not.
>>> I believe that Java implementations that try to generate stack
>>> overflow exceptions usually handle this by always making sure that
>>> they encounter stack overflow exceptions at a known point. For
>>> example, they check at the beginning of each function that the
>>> function, including any native library code it invokes, has enough
>>> stack space to run to completion. This isn't entirely free, though
>>> it may be fairly cheap. It still doesn't strike me as 100% solid,
>>> since the libc API doesn't really include maximum stack depth
>>> bounds, so you have to determine those empirically, and hope libc
>>> doesn't change unexpectedly. And it's easy to miss a path through
>>> libc that has an unexpectedly deep call stack because something
>>> unexpected happened inside the library call.
>> No, it doesn't work that way. If a stack overflow happens in libc
>> code, it won't be caught as a stack overflow exception. Calls to
>> native code don't run in Java state, and any segfault in one results
>> in a crash dump.
> Right. But I thought there was at least some attempt to ensure that
> native code that gets called under the covers as part of a Java library call
> roughly follows the Java stack overflow protocol? If it's user-written
> native code, you could argue that stack overflows are the user's problem.
> But if the code is part of the JVM implementation that seems less
> defensible to me.
True enough. There is some slack allowed for when a spinlock fails
and we have to call into pthread code but I'll grant you that there is
a possibility of an unexpected stack overflow if libc does something
If a thread is not in Java state when a stack overflow segfault
occurs, it'll write-enable the yellow zone and return to complete the
pthread operation, which now has more stack to play with. The size of
the yellow zone should be adequate for any plausible libc operation.
The yellow zone will be protected again when we return to java. The
red zone is beyond the yellow zone, and it's a hard stop: if the libc
code touches that it'll result in a crash dump.
>>> Even if it works, you still have the problem that Java code may have
>>> trouble dealing with the exception in unexpected places.
>> Unexpected like how? HotSpot always bangs the stack at entry to a
>> method, and knows how much scratch space is needed.
> Right. That's what I was alluding to above, and I thought it tried to
> include the JVMs native code stack space requirements. For example, there are
> presumably paths along which monitor entry ends up in libc, e.g. Linux
> futex code, and you presumably want to handle the case in which the futex
> generates a stack overflow? Or does libc run on a separate stack?
As above, possible, but the libc mutex code would have to do something
> In any case, it still ends up as an unchecked error
> that can be thrown from any function call.
> (The spec https://docs.oracle.com/javase/specs/jls/se7/html/jls-11.html#jls-11.1.3
> also still allows it to be thrown asynchronously.)
> How much Java code really tries to reestablish invariants, etc. when
> that happens?
StackOverflowError? Not very much; it's an Error, and you're
basically dead when that happens.
More information about the Gc