Bug 262146 - Enhance debugging experience for AspectJ-enabled programs
Summary: Enhance debugging experience for AspectJ-enabled programs
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.6.2   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-01-23 06:43 EST by Vladimir Piskarev CLA
Modified: 2013-06-24 11:03 EDT (History)
3 users (show)

See Also:


Attachments
Test project (1.25 KB, application/zip)
2009-01-30 09:52 EST, Vladimir Piskarev CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Piskarev CLA 2009-01-23 06:43:04 EST
Current experience debugging AspectJ-enabled programs has several obstacles, some due to bugs and some due to the nature AspectJ performs weaving. I hope this report will serve as a place for discussion of these problems.

Consider an application with a class:

1 class Foo {
2    int i = 3;
3    void foo(Bar bar) {
4      i = 33;
5      ...

Assume that there is a library aspect with an around advice that is (say) load-time weaved to Foo:

aspect FooAspect {
   around() : execution(* *(..)) {
   ...

Let's set a breakpoint at line 4. When the program is suspended on the breakpoint the call stack is as follows:

Foo.foo(Bar) : line 4
....

and the variables are:

this   Foo
   i   3

Note that the parameter 'bar' is not shown among the variables at this point. This seems to be a bug.

Let's go one Step Over. The call stack is:

Foo.foo_aroundBody0(Foo, Bar) : line 4
...
FooAspect.ajc$around$...
Foo.foo(Bar) : line 4
...

and the variables are:

this   Foo <local>
   i   3
bar    Bar

Note that we're now not in the original method 'foo' but in the static method 'foo_aroundBody0' which has 'this' as its first parameter. Also note 'this' is now displayed as a local variable (which it now actually is). 

Not really a bug but this seems confusing for an application developer which knows (and should know) nothing about 'aspect magic' applied behind the scenes. The only thing he knows about is the application code model which he expects to see at run-time the way it originally looked and without unexpected 'anomalies' in the call stack or the variables. This is an important property called 'debug obliviousness'.


Let's turn around and apply some before advice to our Foo:

aspect FooAspect {
   before() : execution(* *(..)) {
   ...

When the program is suspended on the breakpoint the call stack looks like:

<unknown receiving type>.foo(Bar) : line 4
....

and the variables are:

<no variables>, says com.sun.jdi.InternalException: Got error code in reply:35 occured retrieving 'this' from stack frame.

Go a Step Over and the call stack and the variables look correct.

This seems to be a bug that is probably caused by 'this' being placed on the stack only after the advice is called.
Comment 1 Andrew Eisenberg CLA 2009-01-23 11:36:55 EST
There is a lot of work to do here with debugging, both with AJDT and the Compiler.  

One thing that helps a bit is to use the flag XNoInline set to true (available from the compiler options page in AJDT).
Comment 2 Andrew Clement CLA 2009-01-23 12:09:42 EST
As Andrew says, -XnoInline will help.  Many of the symptoms recorded here are captured under other bugs:

bug 194314 - local variable tables incorrect for around weaving.  I think this is mostly what you are observing with the variable names.

bug 80430 - jsr45 support

Comment 3 Vladimir Piskarev CLA 2009-01-26 08:06:07 EST
First of all, thank you for the quick replies!

Unfortunately, -XnoInline did not help. Regarding bug 194314, it does not explain the aforementioned issue with 'before' advice.

But abstracting from these concrete matters, there is a whole 'aspect' (no pun intended) concerned with the 'debug obliviousness' of aspect-enabled programs: namely, the ability to hide AOP activity during debugging so programmers only see the base program‘s behavior and code. At present, AspectJ does not possess this property. However, it seems rather important from the point of view of the 'ordinary' application developer who cares nothing about infrastructure aspects (which work like 'magic' for him) but wants to see the original unmangled code in the debugger. What do you think about it? Thank you.
Comment 4 Andrew Clement CLA 2009-01-26 11:46:58 EST
I think you are right.  Sometimes you want to debug how the aspects are weaving into your code, but sometimes you want to debug only your application.  However, it has to be crystal clear to the user that there is something else going on - that there are aspects in the mix - in case they do impact the running of the application (intentionally or unintentionally). 

I can imagine a debug mode with an option that skips over advice calls - or can be selected and then configured to only step into certain aspects.  Maybe you have a tracing and a caching aspect against your app - you might want to step into tracing but not into caching.  I would consider raising another bug report for an enhancement like this and linking it to this one.
Comment 5 Andrew Clement CLA 2009-01-26 11:47:50 EST
we should probably split out the before() case into another bug too - so that is seen separately to those that are open already for the other symptoms.
Comment 6 Vladimir Piskarev CLA 2009-01-27 01:40:41 EST
I wholeheartedly agree with you that there should be a switch, a separate mode that must be explicitly turned on by the user to make the debugger oblivious to AOP activity. As you say, it can well be configurable. I can even imagine an aspect that is load-time weaved into the debugger and does things like call stack and variables filtering, names unmangling etc.
Comment 7 Vladimir Piskarev CLA 2009-01-27 02:26:19 EST
Split out before() case into bug 262509.
Comment 8 Andrew Clement CLA 2009-01-27 13:58:23 EST
bug 262509 is now fixed.

I believe that mainly leaves bug 194314 (around advice) as the main problematic issue here - i will try and get that done for 1.6.4.

JSR45 support won't be in 1.6.4, and the other features about the UI experience are probably an AJDT thing rather than an AspectJ thing.
Comment 9 Andrew Clement CLA 2009-01-29 16:50:17 EST
194314 is now resolved so local variable tables are correct.  In trying to test it with your instructions, I cant do what you are describing.

After creating Foo/Bar and an aspect, I cannot set a breakpoint on line 4 - or rather I can but when the application is run, the breakpoint is entirely ignored.

Are you using eclipse to debug?
Comment 10 Vladimir Piskarev CLA 2009-01-30 09:51:08 EST
Andrew, I do use eclipse to debug. Build id: M20080911-1700 (3.4.1). AJDT 1.6.1. No issues with the breakpoint. I'm attaching my project zip just in case.
Comment 11 Vladimir Piskarev CLA 2009-01-30 09:52:04 EST
Created attachment 124279 [details]
Test project
Comment 12 Andrew Clement CLA 2009-01-30 16:44:56 EST
hi.  the fact that you are on 1.6.1 AJDT is interesting - I wonder if breakpoint setting has regressed since then...
Comment 13 Andrew Clement CLA 2009-01-30 19:09:29 EST
i imported your project and could set breakpoints ok - no idea why it wasn't behaving for me before...

The local variables all look fine, but I think perhaps some of the line number table entries are off.  Don't know if i'll get time to look at this side of things before 1.6.4 is done.
Comment 14 Andrew Clement CLA 2013-06-24 11:03:34 EDT
unsetting the target field which is currently set for something already released