Re: Re: Re: Re: Try-catch block injection
Nikolas Nehmer <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
Sh... seems to be a conceptual problem on my side :( To explain my issue. I'm trying to log the old values of local variables everytime a new value is assigned to that variable. Of cource, the first time a value is assigned, the "old" value does not exist as the variable in not initialized. To cope with that problem, i thought it would be a great idea to catch the VerifyError and pass default values to my logging component for the exceptional case. Obviously this does not work! Eugene Kuleshov schrieb: > 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] >> >> >> -- 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