Closed aionbot closed 5 years ago
Comment by jeff-aion (on Tuesday Nov 20, 2018 at 20:38 GMT)
Interestingly, section 4.9.5 of the class file spec seems to imply that they don't do this (more evidence that this is a bug): https://docs.oracle.com/javase/specs/jvms/se6/html/ClassFile.doc.html
The handler for an exception will never be inside the code that is being protected.
Issue created by jeff-aion (on Tuesday Nov 20, 2018 at 20:35 GMT)
javac
seems to compilefinally
blocks with a very strange exception handling pattern: the first 2 bytecodes are covered by thefinally
handler, looping back to themselves. A description of this pattern can be found here: https://stackoverflow.com/questions/6386917/strange-exception-table-entry-produced-by-suns-javacThis seems as though it must be a bug since normal
finally
behaviour does not state that exceptions thrown in thefinally
block will result in the thread looping forever. Due to the mundane nature of the first 2 bytecodes of afinally
block, however, this doesn't seem to matter, in practice.In AVM, however, we can see this problem. Since we inject instrumentation to bill the block, at the beginning of a
catch
block, any attempt tothrow
an instrumentation-related exception will result in the theoretical infinite loop becoming reality.Ideally, we would reject exception handlers which target their own range but this pattern seems common and there could be other cases of looping exception handlers which don't overlap themselves (2 which resolve to each other, for example). Hence, I think we should approach this, in the present (and we could relax this requirement later), as a rule (which we need to add to the specification - at least for this version) that we will strip out any exception handler entries where the target is not a strictly greater index than the range body.
This would strip out this case and would also break the other cases of looping handlers. While there are legitimate and safe ways to use such backward-target handlers, I suspect that they don't occur in common code and we can account for them, using a more complex algorithm (some sort of graph solver) when/if this issue comes up.
I will prototype this solution and see how it works out.