Bug 277959 - VerifyError "Stack size too large" thrown when advising method which invokes a static method
Summary: VerifyError "Stack size too large" thrown when advising method which invokes ...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.6.4   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 1.6.5   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-05-26 18:33 EDT by Erik Noren CLA
Modified: 2009-05-27 20:17 EDT (History)
1 user (show)

See Also:


Attachments
Class which contains the advice (618 bytes, text/plain)
2009-05-26 18:33 EDT, Erik Noren CLA
no flags Details
Test class which causes a VerifyError when advice is applied from Advice.java (783 bytes, text/plain)
2009-05-26 18:35 EDT, Erik Noren CLA
no flags Details
Code base aspect which applies advice to AOPTest which displays the same bad behavior (377 bytes, text/plain)
2009-05-27 14:39 EDT, Erik Noren CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Erik Noren CLA 2009-05-26 18:33:19 EDT
Created attachment 137239 [details]
Class which contains the advice

I have attached 2 classes which easily demonstrate the problem:

1> Advice.java - Class which defines the advice to be applied to the test class
2> AOPTest.java - The class which has a method cleanup that is as simple as:

"
    public static void doSomething() {}

    public static void cleanup() {
        try {
            doSomething();
        } catch(Exception ex) {
            // ignore
        }
    }
"

When the main method is called on AOPTest.java the following output occurs:

Exception in thread "main" java.lang.VerifyError: (class: example/AOPTest, method: cleanup_aroundBody2 signature: (Lorg/aspectj/lang/JoinPoint;)V) Stack size too large
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:164)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:87)


Note that "cleanup" does not have to be static, so the advised method being static does not seem to be an issue.  There are also workarounds mentioned in AOPTest.java, however the problem is of course that the workaround is in the code being advised and I have not found one yet that can be applied at the pointcut.


I am using Java 1.5.0_14, however I have tried it with 15 and 16 and they both fail.  Interestingly enough though I tried it with 1.5.0_1 and it worked, so something changed so cause this.  I also was originally running with AspectJ 1.6.2 and this problem occurred there as well.

This also occurs using LTW as well as compile time weaving.
Comment 1 Erik Noren CLA 2009-05-26 18:35:08 EDT
Created attachment 137240 [details]
Test class which causes a VerifyError when advice is applied from Advice.java
Comment 2 Andrew Clement CLA 2009-05-26 18:54:39 EDT
you could try using a code style aspect (rather than annotation style) as a possible workaround until I can fix this.
Comment 3 Erik Noren CLA 2009-05-27 14:38:51 EDT
I tried doing a code based aspect and the problem still exists.  I am attaching the code based aspect that I used to apply advice on the previously attached AOPTest class.  Please let me know if there is an additional path on the code based aspect that I could try.

Thanks
Comment 4 Erik Noren CLA 2009-05-27 14:39:42 EDT
Created attachment 137380 [details]
Code base aspect which applies advice to AOPTest which displays the same bad behavior
Comment 5 Andrew Clement CLA 2009-05-27 20:17:28 EDT
fixed.  The problem is that there is no 'apparent' activity against the stack in that simple method with the try catch, so it assigns it a stack depth of 0.  This is incorrect because there is an exception handler and so at least one item gets put on the stack if the ex handler is entered.  I've fixed it to allow for this situation.  Your variants of the code simply caused some stack activity:

    public static void cleanup() {
        try {
            int x = 1;
            doSomething();
        } catch(Exception ex) {
            // ignore
        }
    }

or didnt have an exception handler:

    public static void cleanup() {
        doSomething();
    }                                      

and then it got the depth correct anyway.

thanks for simple test case.  Fix will be in next dev build.