Working with Try / Catch exceptions in Java bytecode? ("stack height mismatch")

I am trying to do some error handling in Java bytecode. First I tried to implement some catch-like routines, where I would check the error condition and move on to the corresponding routine, a bit like:

iconst_1 iconst_0 dup ifeq calldiverr goto enddivtest calldiverr: jsr divError enddivtest: idiv ...More instructions... divError: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "Oh dear you divided by 0!" invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V 

The problem with the above is that when I have several instructions that go to this subroutine, I get an error message when starting the bytecode, saying that the stack height is inconsistent.

Perhaps using exceptions is the best way around this?

From some googling, I found that you can instantiate Exception classes and initialize them with something like:

 new java/lang/Exception dup ldc "exception message!" invokespecial java/lang/Exception/<init>(Ljava/lang/String;)V 

I also found that you can send them using athrow , and that looks fine.

What baffles me is how the exceptions are caught. There seems to be a magical “exception table” that glues throwing and catching exceptions together, but I don't know how to determine one of them when writing bytecode from scratch (and build using Jasmin). Can someone tell me the secret of creating an exception table? And maybe give me an example of exception handling to be compiled using jasmin?

+6
source share
3 answers

In the end, I came up with a better solution than jsr - defining a method using .method in Jasmin. I just used invokestatic to call my error handler as soon as I found the error.

For those who are looking for the actual handling of exceptions - I think that defining an exception table in Jasmin can be done using .catch , but I did not look at it the way the method definition solved my problem.

Edit:

In the end, I had to look at .catch and find that it is very easy to use. He documented here .

+2
source

First of all, it is worth noting that class files from version 51.0 may not contain a jsr instruction. Repeat the code or use the method.

At each point in the bytecode, the static type of each element in the frame must be known. Each frame is not a call stack.

As a rule, you do not want to play with huge large stacks. Store temporary files in local variables to keep things simple.

If an exception is thrown, then obviously the frame could have content from anywhere that could throw an exception. Thus, the content is discarded and replaced by an exception. In any case, you will not be able to return and resume using the contents of the frame.

0
source

The jsr validation jsr quite complex, and as Tom pointed out, the jsr is out of date. Therefore, it is better to avoid it.

My jsr memory is a bit fuzzy, but ...

(Updated). The bytecode verifies that wherever two control flows are combined, the stack depth should be the same along both branches. jsr routines jsr exempt from this rule to the point. Several exception points with different stack depths can “reach” the same jsr subroutine, but the net change in the stack depth from jsr current record to the next ret should be zero (or actually minus 1, because the reason for the exception is always clicked on the record in the procedure).

In addition, while the jsr routine can “escape” and return back to the normal control flow, if so, jsr not exempt from the stack depth rule for junction points. This greatly limits situations where you can do this, as the jsr routine can be entered with different stack depths.

(And I have no doubt that everything worked out for me, but this is the best I can do.)

(I don’t quite understand how you plan to get around your jsr problem with exceptions.)

(In addition, Sun made bytecode writing much more difficult with 4 or 5 (I don’t remember which one), which makes it almost impossible for manual bytecodes. They did this because they did not know how to quickly execute checking is enough to defeat the IBM verifier differently, but that's another matter.)

0
source

Source: https://habr.com/ru/post/903637/


All Articles