Re: Re: Re: Try-catch block injection
Eugene Kuleshov <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
If you look at the stack trace of that VerifyError, you should see that it is thrown before your code is executed, i.e. when your transformed class is loaded. Basically the bytecode you generating is invalid and you can't recover from that within an invalid method code. So, you should make sure that all your transformed code pass trough CheckClassAdapter.verify() regards, Eugene On Mon, Mar 22, 2010 at 1:05 PM, Nikolas Nehmer <[email protected]> wrote: > Thanks for your answer. Some points are getting clearer now. But I still > have some issues. I can't manage to catch the VerifyError even including the > try-catch block on source code level. > If i use the following code snippet: > try { > int xxx = 5; > } catch (VerifyError e) { > System.out.println("Hello"); > } > > injecting an xLOAD before the xSTORE statement without inserting additional > labels the vm is terminated because of an uncaught exception (VerifiyError). > The catch-block is not executed! > > InsnList list = instructions; > //currentInsnNode represents xSTORE > list.insertBefore(currentInsnNode,new VarInsnNode(Opcodes.ILOAD, > ((VarInsnNode)currentInsnNode).var)); > > Instead injecting an exception initialization at the same place, works out > perfectly, i.e. the surrounding try-catch block catches and handles the > exception. > > list.insertBefore(currentInsnNode, new TypeInsnNode(Opcodes.NEW, > "java/lang/VerifyError")); > list.insertBefore(currentInsnNode, new InsnNode(Opcodes.DUP)); > list.insertBefore(currentInsnNode, new MethodInsnNode(Opcodes.INVOKESPECIAL, > "java/lang/VerifyError","<init>","()V")); > list.insertBefore(currentInsnNode, new InsnNode(Opcodes.ATHROW)); > > Any ideas what the problem might be? > > Cheers > Nikolas > > Eugene Kuleshov schrieb: >> >> In regards to your example, if it wasn't clear from my previous >> email you need to insert start label BEFORE wrapped block and end >> label - AFTER that block. Also your code always fall into the catch >> block (with or without the exception), so content of the stack doesn't >> match for those two cases. So, as I already suggested before, use >> ASMifier on a code compiled from a Java snipped before and after your >> transformation and you should see what I mean. >> >> BTW, instead of loading variable you can also duplicate value used >> by xLOAD opcodes from the stack, but that will certainly affect the >> stackmap structure and maxstack value. >> >> regards, >> Eugene >> >> >> On Mon, Mar 22, 2010 at 10:05 AM, Nikolas Nehmer >> <[email protected]> wrote: >> >>> >>> By basic idea is as follows: >>> I try to log local variable access...logging the "old" variable value. To >>> achieve that goal, a method's bytecode is parsed and the following code >>> is >>> injected (in this case for an ISTORE op) - passing the variable's stack >>> frame position and the old value to my logger. The currentIsnsNode in >>> that >>> case would be the ISTORE. >>> >>> tempList.add(new LdcInsnNode(((VarInsnNode)currentInsnNode).var)); >>> tempList.add(new VarInsnNode(Opcodes.ILOAD, >>> ((VarInsnNode)currentInsnNode).var)); >>> tempList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, logger,localLogger, >>> ("(II)V"))); >>> >>> Unfortunately, thr ILOAD might throw a VerifyError if the local variable >>> is >>> not initialized. To cope with that situation, I would like to surround >>> the >>> code block inserted for logging, with a try catch block, catching the >>> VerifyError and passing a "default" value to the logger instead of >>> loading >>> the current value. >>> >>> thanks in advance! >>> Nikolas >>> >>> Eugene Kuleshov schrieb: >>> >>>> >>>> Not sure what suggestion you are looking for, but your code is >>>> incomplete to drive any conclusions (e.g. what's the >>>> currentInsnNode?). >>>> I'd suggest to forget about stackmap frames for now, it is going to >>>> work without them just fine and you can get back to them when you get >>>> a better grip on a bytecode. >>>> Also, write your java code before and after transformation and use >>>> ASMifier to get the code to generate bytecodes, so you can compare >>>> what changes. >>>> >>>> Anyways, from what I read, your code is transforming this: >>>> >>>> currentInsnNode >>>> >>>> into this: >>>> >>>> >>>> { >>>> startLabel (created by you) >>>> endLabel (created by you) >>>> } catch(Throwable e) { >>>> logger.testTryCatch(); >>>> } >>>> currentInsnNode >>>> ... >>>> >>>> Note that you also are NOT consuming the exception value off the stack. >>>> >>>> regards, >>>> Eugene >>>> >>>> >>>> On Mon, Mar 22, 2010 at 9:03 AM, Nikolas Nehmer >>>> <[email protected]> wrote: >>>> >>>> >>>>> >>>>> Hi, >>>>> >>>>> I'm trying to do the following transformation based on bytecode >>>>> injection: >>>>> >>>>> startLabel: >>>>> foo...; >>>>> endLabel >>>>> >>>>> into >>>>> >>>>> try { >>>>> startLabel: >>>>> foo...; >>>>> endLabel >>>>> } catch (VerifyError e) { >>>>> //doSomething; >>>>> } >>>>> >>>>> Currently, my code looks like this (raising a >>>>> java.lang.ClassFormatError): >>>>> >>>>> LabelNode startLabel = new LabelNode(); >>>>> tempList.add(startLabel); >>>>> LabelNode endLabel = new LabelNode(); >>>>> tempList.add(endLabel); >>>>> //catch block >>>>> int numberOfLocalVariables = 0; >>>>> Object[] localVariableTypes = new Object[0]; >>>>> int numberOfStackElements = 0; >>>>> Object[] stackElementTypes = new Object[0]; >>>>> tempList.add(new FrameNode(Opcodes.F_FULL, numberOfLocalVariables, >>>>> localVariableTypes, numberOfStackElements, stackElementTypes)); >>>>> tempList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, >>>>> logger,"testTryCatch", >>>>> ("()V"))); >>>>> >>>>> list.insertBefore(currentInsnNode, tempList); >>>>> list.insert(new FrameNode(Opcodes.F_SAME, >>>>> numberOfLocalVariables, >>>>> localVariableTypes, numberOfStackElements, stackElementTypes)); >>>>> tryCatchBlocks.add(new TryCatchBlockNode(startLabel, endLabel, >>>>> endLabel, >>>>> "java/lang/Throwable")); >>>>> >>>>> Any suggestions? >>>>> >>>>> Cheers >>>>> Nikolas >>>>> >>>>> >>>>> -- >>>>> You receive this message as a subscriber of the [email protected] mailing >>>>> list. >>>>> To unsubscribe: mailto:[email protected] >>>>> For general help: mailto:[email protected]?subject=help >>>>> OW2 mailing lists service home page: http://www.ow2.org/wws >>>>> >>>>> >>>>> >>>>> >>> >>> -- >>> Dipl.-Inf. Nikolas Nehmer, >>> Dept. of Computer Science. University of Kaiserslautern P.O. Box 3049, >>> 67653 >>> Kaiserslautern, Germany. >>> room 36/308, phone: +49 (0) 631 - 205 2644, fax: +49 (0) 631 - 205 3299 >>> mail: [email protected] >>> >>> >>> > > > -- > Dipl.-Inf. Nikolas Nehmer, > Dept. of Computer Science. University of Kaiserslautern P.O. Box 3049, 67653 > Kaiserslautern, Germany. > room 36/308, phone: +49 (0) 631 - 205 2644, fax: +49 (0) 631 - 205 3299 > mail: [email protected] > >
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws