Asynchronous exceptions in jvm - java

This paragraph is from the jvm specs:
A Java Virtual Machine may permit a small but bounded
amount of execution to occur before an asynchronous exception
is thrown. This delay is permitted to allow optimized code
to detect and throw these exceptions at points where it is
practical to handle them while obeying the semantics of the Java
programming language.
I'm having trouble understanding the second part, ie the reason jvm lets the thread run for some time before stopping it.

Let’s recall the definition of asynchronous exceptions:
Most exceptions occur synchronously as a result of an action by the thread in which they occur. An asynchronous exception, by contrast, can potentially occur at any point in the execution of a program.
So when an exception occurs as a result of an action, you simply know that, e.g. when executing an athrow instruction an exception will occur unconditionally, when executing an integer division, the divisor may be zero, or when accessing an object member, the reference may be null. This is a limited set of actions and the optimizer tries its best to reduce it further, using code analysis to prove that the divisor can not be zero, resp. the reference can not be null at specific code locations. Otherwise, it must insert a check for the erroneous condition to generate and handle an exception if necessary. But only at these specific code locations.
In contrast, the asynchronous exception can occur at every code location and may require an explicit check of the “did another thread call stop on my thread since the last check” kind. You don’t want such checks to be performed after every instruction, as that would imply spending more time on such checks than on the actual work.
Hence, it is allowed to perform more than one instruction until the next check, as long as it is guaranteed that the time to reach the next check will be bounded, so this will rule out backward branches with an unpredictable number of iterations without a check. Also keep in mind that in optimized code, there might be uncommitted actions, e.g. the values of modified variables are held in CPU registers. So even after detecting that an asynchronous exception occurred, the code must commit these pending actions, e.g. write back these values to the shared memory, before leaving the code to respond to the exception.

Related

What does "execution trace" mean in Java Memory Model

The part of the language specification dedicated to the Java Memory Model (JMM) (link) mentions "execution trace" a lot.
For example right from the start:
A memory model describes, given a program and an execution trace of that program, whether the execution trace is a legal execution of the program. The Java programming language memory model works by examining each read in an execution trace and checking that the write observed by that read is valid according to certain rules.
But I cannot find there any description/definition of this term.
So, what is "execution trace" exactly according to the JMM, and what exactly does it consist of?
References to specific places in the language specification text are most welcome.
You're right; it's not very clear. They also refer to it as "program trace", and simply "trace" on its own.
The following is a quote:
Consider, for example, the example program traces shown in Table 17.4-A.
Table 17.4-A.
Thread 1
Thread 2
B = 1;
A = 2;
r2 = A;
r1 = B;
So, it's simply an ordered list of statements, per thread, representing one possible permutation of how the statements may be executed (since statement may be reordered). A trace may be valid or invalid within the JMM; they are used to exemplify what is legal and what is not.
This is not a full-fledged answer, but I think this is worth mentioning.
Even if we don't know what an "execution trace" is in details, we can deduce which information it should provide.
Let's read the first paragraph of 17.4. Memory Model:
A memory model describes, given a program and an execution trace of that program, whether the execution trace is a legal execution of the program. The Java programming language memory model works by examining each read in an execution trace and checking that the write observed by that read is valid according to certain rules.
This means that "a program" (i.e. source code) and "an execution trace" should provide all the information required to determine whether the program execution is legal.
The information is described in 17.4.6. Executions.
I'm not going to copy-paste it here because it's too long.
I'll try to explain it in simple words instead:
a program consists of statements, each statement consists of (possibly nested) expressions evaluated in some order
an execution of a thread can be represented as a sequence of actions: one action per every simple expression
an execution of a program is several threads executing in parallel
an execution trace should provide information about actions performed during the program execution, i.e. it should provide provide the following information:
all executed actions: a sequence of actions per every thread
Note: the JMM only cares about so called inter-thread actions (17.4.2. Actions):
An inter-thread action is an action performed by one thread that can be detected or directly influenced by another thread
Inter-thread action kinds:
read/write
volatile read/write
lock/unlock
various special and synthetic actions (e.g. thread start/stop, etc.)
for every action it should store:
thread id
action kind
what expression in the source code it corresponds to
for write and volatile write: the written value
for read and volatile read: the write action, which provided the value
for lock/unlock: the monitor being locked/unlocked
various relations with other actions (e.g. position in a so-called synchronization order for synchronization actions)

In parallel processing, is there the concept of "uninterruptible block"? If not, why not?

Summary
From my studies, I don't remember that a concept such "uninterruptible block" exists, and I did not find it either with a quick Google search.
Expected answer
yes, it does exist, and the proper term for that is ... (in this case, it would be nice, if someone could explain me, why it does not exist in Java)
no, it does not exist, because ...
Definition
By "uninterruptible block", I mean a section of code, in a multi-threading context, which, once starts execution, cannot be interrupted by other threads. I.e., the CPU (or the JVM), won't run any other thread at all, until the "atomic block" is left.
Note, that this is not the same as a section marked by lock/mutex/... etc., because such section can not be interrupted only by other threads, which acquire the same lock or mutex. But other threads can still interrupt it.
EDIT, in response to comments It would be fine also, if it affected only the threads of the current process.
RE. multiple cores: I would say, yes, also the other cores should stop, and we accept the performance hit (or, if it is exclusive only for the current process, then the other cores could still run threads of other processes).
Background
First of all, it is clear, that, at least in Java, this concept does not exist:
Atomic as in uninterruptible: once the block starts, it can't be interrupted, even by task switching.
...
[this] cannot be guaranteed in Java - it doesn't provide access to the
"critical sections" primitives required for uninterruptibility.
However, it would have come in handy in the following case: a system sends a request and receives response A. After receiving the response, it has max. 3 seconds to send request B. Now, if multiple threads are running, doing this, then it can happen, that after receiving response A, the thread is interrupted, and one or more threads run, before the original thread has the chance to send out request B, and thus misses the 3 seconds deadline. The more threads are running, the bigger the risk that this happens. By marking the "receive A to send B" section "uninterruptible", this could be avoided.
Note, that locking this section would not solve the issue. (It would not prevent the JVM, from e.g. processing 10 new threads at the "send request A" phase, right after our thread received response A.)
EDIT: Re. global mutex. That would also not solve the issue. Basically, I want the threads to make Request A's (and some other stuff) simultaneously, but I want them to stop, when another thread received Response A, and is going to make Request B.
Now, I know, that this would not be a 100% solution either, because those threads that don't get scheduled right after receiving response A still could miss the deadline. But, at least, those who do, would for sure send out the second request in time.
Some further speculation
The classic concurrency problem a++ could be simply solved by uninterruptible { a++; }, without the need for locks (which can cause dead-lock, and, in any case, would probably be more expensive in terms of performance, than simply executing the three instructions required by a++, with a simple flag, that they must not be interrupted).
EDIT RE. CAS: of course, that's another solution too. However, it involves retrying, until the write succeeds, and it is also slightly more complex to use (at least in Java, we have to use AtomicXXX, instead of the primitive types for that).
I know, of course, that this could be easily abused, by marking large blocks of code as uninterruptible, but that is true for many concurrency primitives as well. (What's more, I also know, that my original use case would be also kind of an "abuse", since I'd be doing I/O in an uninterruptible block, still it would have been worth at least a try, if such concept did exist in Java.)

Valid use case for (the deprecated) myThread.stop()?

The prevailing religion of Java today heavily forbids the use of the stop() instance method on a Thread[1] [2] [3]. It's marked as Deprecated in the official documentation, with a message that begins with:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. [...]
There is even a whole article supplied that goes into further detail. (Especially that ThreadDeath is silent when it gets to the top, and even if you guard against it, you can't guard against Thread.stop(Throwable t) anyway.)
In general, I agree with what that article is worried about, and with the answers to the related question on StackOverflow — in almost all the use cases in the world there is a much better way than stop(). But not all.
Here is a use case that I'm struggling to think of a better way for. I invite your suggestions.
Use case
I'm working with an interactive console running on top of Java, that allows the user run arbitrary Java statements and Python functions that call Java, in an interactive interpreted way. (See Jython console for screenshots.)
Now, the user can write arbitrary functions. Some of them might call Java methods that result in infinite loops that print a lot of output, almost saturating the system, so that it becomes painfully slow to respond.
When the user messes up like this, I need to give them a chance to kill the thread (using a button), and salvage the remainder of the work that they have produced in their session and stored in local variables.
If calling interrupt() on the thread fails, (e.g. if it never goes into waiting state while stuck in its infinite loop), then we are faced with two options that I can see: (1) kill the application outright or (2) use stop() on the bad thread, and let the user salvage whatever is left that hadn't been corrupted.
Yes I know that some objects may have been damaged and won't work properly. But we're talking about salvaging anything that may have been left in a valid state (which is probably pretty much everything, except one or two things).
Can anybody see any problems with this reasoning? And if this turns out to be a valid use-case, then does it mean the method shouldn't be deprecated :) ?
Calling Thread.stop() is a bad idea. End of story.
It may work in practice but you sacrifice most of the JVM's concurrency guarantees in the process. Your whole program is essentially running undefined behavior. It isn't simply the thread or the data in the thread that may become corrupted, but any part of the JVM that happens to be in a vulnerable state when the thread is killed.
It sounds like you're looking for someone to confirm that your use case somehow avoids the risks to the JVM. It doesn't, so you're not likely to get such a confirmation. If you don't see issues more power to you, but don't be surprised when it fails in inexplicable or dangerous ways.
As Peter Lawrey suggests you should be running this untrusted code in an isolated JVM, where the OS's process management can support killing resource-hogging processes. If you can't do that because you're passing around strange resources like open file descriptors that is your problem.

How can I abandon a LuaJ coroutine LuaThread?

I am experimenting with a game mechanic in which players can run scripts on in-game computers. Script execution will be resource limited at a gameplay level to some amount of instructions per tick.
The following proof-of-concept demonstrates a basic level of sandboxing and throttling of arbitrary user code. It successfully runs ~250 instructions of poorly crafted 'user input' and then discards the coroutine. Unfortunately, the Java process never terminates. A little investigation in shows that the LuaThread created by LuaJ for the coroutine is hanging around forever.
SandboxTest.java:
public static void main(String[] args) {
Globals globals = JsePlatform.debugGlobals();
LuaValue chunk = globals.loadfile("res/test.lua");
chunk.call();
}
res/test.lua:
function sandbox(fn)
-- read script and set the environment
f = loadfile(fn, "t")
debug.setupvalue(f, 1, {print = print})
-- create a coroutine and have it yield every 50 instructions
local co = coroutine.create(f)
debug.sethook(co, coroutine.yield, "", 50)
-- demonstrate stepped execution, 5 'ticks'
for i = 1, 5 do
print("tick")
coroutine.resume(co)
end
end
sandbox("res/badfile.lua")
res/badfile.lua:
while 1 do
print("", "badfile")
end
The docs suggest that a coroutine that is considered unresumable will be garbage collected and an OrphanedThread exception will be thrown, signalling the LuaThread to end - but this is never happening. My question is in two parts:
Am I doing something fundamentally wrong to cause this behaviour?
If not, how should I handle this situation? From the source it appears that if I can get a reference to the LuaThread in Java I may be able to forcibly abandon it by issuing an interrupt(). Is this a good idea?
Reference: Lua / Java / LuaJ - Handling or Interrupting Infinite Loops and Threads
EDIT: I have posted a bug report over at the LuaJ SourceForge. It discusses the underlying issue (threads not being garbage collected as in the Lua spec) and suggests some ways to work around it.
It seems to be a limitation of LuaJ. I submitted a ticket earlier this year on Sourceforge as I see you've also done. The LuaThread class doesn't store references to the Java threads it creates, so you can't interrupt() those threads without modifying the LuaJ core to expose them:
new Thread(this, "Coroutine-"+(++coroutine_count)).start();
It may be dangerous to interrupt those threads without adding appropriate cleanup code to LuaJ.
Documentation that you provided for OrphanedThread also tells us that scope is the defining condition:
"Error sublcass that indicates a lua thread that is no longer referenced has been detected. The java thread in which this is thrown should correspond to a LuaThread being used as a coroutine that could not possibly be resumed again because there are no more references to the LuaThread with which it is associated. Rather than locking up resources forever, this error is thrown, and should fall through all the way to the thread's Thread.run() method."
Your code example doesn't cause all LuaThread references to disappear, so you shouldn't expect an exception to be thrown. CoroutineLib documentation indicates: Coroutines that are yielded but never resumed to complete their execution may not be collected by the garbage collector, so an OutOfMemoryError should actually be expected from the code you listed on SourceForge, if I'm not mistaken. LuaThread:52 also specifies: Applications should not catch OrphanedThread, because it can break the thread safety of luaj., which is yet another obstacle.
There also seem to be differences between empty and non-empty while loops in Lua/J. IIRC, empty loops (while true do end) don't obey all coroutine hook/tick rules. *Because no actions occur in an empty loop, there's no opportunity for certain hooks to occur (I need to test this again so please correct me otherwise!).
A forked version of LuaJ with the functionality we're looking for is used in the ComputerCraft mod for Minecraft, though it's designed only for the mod and isn't open source.

Java invariant exception

I have a project in which certain data has invariants which are not enforceable using language constructs, but I've intended to write my code such that they are maintained. If they are for some reason broken, it means that my code is buggy. I have some sanity check code which can discover if these invariants have been broken, but I'm not sure what is the canonical Java approach to responding to such a condition - is there some standard exception that I should throw? Use an assert?
Note that this is an issue of a value being set incorrectly at some point. The error itself does not occur at the time of the sanity check, but rather it occurred in the past, and the sanity check is just now discovering it (ie, it's not bad that the sanity check itself is running, it's just bad that the check failed).
Thanks!
Throw an IllegalStateException. It is meant specifically for purposes like this.
Deciding how your application would react to a broken invariant would be a sensible first step
In case a broken invariant is unrecoverable and basically means a bug a code, i second an answer about IllegalStateException.html (you may want to add some useful context for debug purposes ,e.g. variables in broken invariant) - such unchecked exception would stop a running thread
In case you can recover from broken invariant (by replacing some arguments with sensible default, giving it a second try) - you may want to throw a checked exception and catch it on one of upper layers and execute plan B

Categories

Resources