Bug 82570 - Weaved code does not include debug lines
Summary: Weaved code does not include debug lines
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.2.1   Edit
Hardware: PC Windows XP
: P2 blocker (vote)
Target Milestone: 1.5.2   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-11 11:17 EST by Chris Nappin CLA
Modified: 2006-05-16 10:38 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Nappin CLA 2005-01-11 11:17:46 EST
I am attempting to use AspectJ and output all classes in debug mode (required by
our code coverage instrumentor). However any code introduced by our aspects to
production classes does not include debug line information.

Our ant script uses the iajc task as follows:

 <iajc ... debug="true" .. />

We have an aspect that introduces a public, no-arguments constructor into
various classes. If I enable this aspect, then do a clean build, I get the
following error from our code coverage tool:

 [jblanket] java.lang.UnsupportedOperationException: No line numbers detected in
 com.abmuk.oms.core.model.core.XMLObject.<init>. Either remove the 'oneLineFile'
 tag or turn debug on when compiling.

If I remove that aspect, we get no errors about debug line information.

I've tried debug="true" or debugLevel="lines,vars,source", with no success.

This issue is preventing our Unit Test suite from executing.

If you require any further information, please don't hesitate to email me.

Cheers,

  Chris Nappin.
Comment 1 Andrew Clement CLA 2005-01-11 17:47:06 EST
We don't currently create line number information for members created in a
target type to support ITDs.  The reason is that the methods/ctors added to the
target type are simply forwarding methods that delegate to the aspect to execute
the intended behavior.  Here is a decompiled class that had a method and ctor
ITD'd upon it:

public A();
  Code:
   Stack=1, Locals=2, Args_size=1
   0:   invokestatic    #30; //Method
X.ajc$preInterConstructor$X$A:()[Ljava/lang/Object;
   3:   astore_1
   4:   aload_0
   5:   invokespecial   #11; //Method java/lang/Object."<init>":()V
   8:   aload_0
   9:   invokestatic    #33; //Method X.ajc$postInterConstructor$X$A:(LA;)V
   12:  return

public void sayhi();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokestatic    #25; //Method X.ajc$interMethod$X$A$sayhi:(LA;)V
   4:   return

You can see in each case the body of the member in the class simply forwards the
request to an ajc$XXX method in the aspect (called X in this case).

So, any line number information we did add to the members added to a class for
ITDs would be 'fake' - as it wouldn't refer to anything that really existed in
the source file for the class.  However, we can do this - there is a precedent
in that we already do create fake line number tables for methods to support
inlined around advice.  I'm just not sure that I want to create too much 'fake'
information in everything the weaver creates just to support this use case - I
think we'd get a lot of push back about unnecessary code bloat.

But I'm keen to help you if we can - I'm currently right in the midst of our
debug support so you raised this bug at the right time :)  Is there no way the
tool can be tailored to be a little less strict on what should have debug info
attached? After all, coverage information for these delegator methods would
simply be measuring coverage of AspectJ 'generated' code - coverage of the
actual body of the ctor would count when the delegated ctor (in the aspect) was
executed.

Andy.
Comment 2 Chris Nappin CLA 2005-01-12 04:42:28 EST
Thanks for looking into this so quickly! I'm not sure about your comment on 
code bloat, if compiling classes in debug mode then I'd certainly expect to 
get larger class files?

I will try to see if I can get the coverage tool we're using (JBlanket) to 
side-step these constructors as a special case. I couldn't get it to ignore 
methods previously, although it should be able to, and I'm not sure it 
supports ignoring constructors. It may be that we have to move to a different 
coverage tool, but I believe a lot of them instrument code in a very similar 
way, using classes built in debug mode, and the CGLIB or bcel libraries.

Chris.
Comment 3 Chris Nappin CLA 2005-01-12 09:32:10 EST
Hi,

  I've had a play with JBlanket's exclusion mechanism and unfortunately it 
seems to work by filtering the results, rather than reducing which blocks of 
code it adds instrumentation to. I imagine that other tools work in a similar 
way. Is there any possibility that AspectJ can be updated to honour 
the "debug" flag for introduced code?

Chris. 
Comment 4 Andrew Clement CLA 2005-01-12 11:39:38 EST
I've just tried a comparable case that occurs in pure java - to see what happens
for generated code like this.  Here is a simple program:

public class Test {
  private int i;
  private  class Inner {
    public void aMethod() {
     System.err.println(i);
    }
  }
}

So that 'Inner' can see 'i', an accessor method for it is generated when you
compile this program, on javap -verbose I see this:

public Test();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #2; //Method java/lang/Object."<init>":()V
   4:   return
  LineNumberTable:
   line 1: 0
   line 6: 4

static int access$000(Test);
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   getfield        #1; //Field i:I
   4:   ireturn
  LineNumberTable:
   line 1: 0
  Synthetic: true

}

So, there is a line number table with just one entry in for the generated method
(and it is marked synthetic) - I guess we should do the same for AspectJ
generated methods !
Comment 5 Andrew Clement CLA 2005-01-19 05:26:11 EST
Fix checked in - we add a single line number table entry if one does not exist
for the generated methods.  This adds 12bytes per method that previously didn't
have a table.  Creation of it could be made conditional on the value of the -g:
flag - but after some minimal testing we don't seem to respect -g:none correctly
so I'm leaving someone else to fix that in a separate bug.

I've not added extra logic to add extra synthetic markers here and there - it
doesn't seem necessary to ensure the tests pass, but I hope debuggers don't
start having problems with these unusual tables around.

Waiting for build ...
Comment 6 Andrew Clement CLA 2005-01-19 11:12:38 EST
BUILD COMPLETE -  build.439
Date of build: 01/19/2005 11:53:40
Time to build: 112 minutes 16 seconds
Last changed: 01/19/2005 09:36:48
Last log entry: Fix for Bug 82570: Weaved code does not include debug lines
Latest good AspectJ jar available at:
download.eclipse.org/technology/ajdt/dev/aspectj-DEVELOPMENT.jar
Comment 7 Chris Nappin CLA 2006-03-07 09:51:55 EST
Hi, I'm now trying again to introduce AspectJ into our project, but am hitting against this same issue again. 

I'm now using AspectJ 1.5.0, JDK 1.4.2 and Windows XP.

This time I have one simple Aspect that has a single "around" advice added to various classes in our project. I'm compiling using iajc with debug set to "true", but I get the following error from JBlanket:

 [jblanket] java.lang.UnsupportedOperationException: No line numbers detected in
 com.abmuk.oms.core.common.logging.Timer.ajc$around$com_abmuk_oms_core_common_lo
gging_Timer$1$e548cc5bproceed. Either remove the 'oneLineFile' tag or turn debug
 on when compiling.
 [jblanket]     at csdl.jblanket.modifier.MethodModifier.processMethod(MethodMod
ifier.java:121)
 [jblanket]     at csdl.jblanket.modifier.ClassModifier.modifyMethods(ClassModif
ier.java:123)
 [jblanket]     at csdl.jblanket.modifier.Modifier.processIncludeClasses(Modifie
r.java:282)
 [jblanket]     at csdl.jblanket.modifier.Modifier.modify(Modifier.java:520)
 [jblanket]     at csdl.jblanket.modifier.Modifier.main(Modifier.java:662)
 [jblanket]     at csdl.jblanket.ant.JBlanketModifierTask.execute(JBlanketModifi
erTask.java:366)
Comment 8 Andrew Clement CLA 2006-03-07 12:04:42 EST
you could try compiling with -XnoInline to see if that helps...
Comment 9 Chris Nappin CLA 2006-03-08 06:18:45 EST
Thanks for the suggestion. Unfortunately this has no affect, I still get the same error about missing line numbers:

 [jblanket] java.lang.UnsupportedOperationException: No line numbers detected in
 com.abmuk.oms.core.common.logging.Timer.ajc$around$com_abmuk_oms_core_common_lo
gging_Timer$1$e548cc5bproceed. Either remove the 'oneLineFile' tag or turn debug
 on when compiling.
 [jblanket]     at csdl.jblanket.modifier.MethodModifier.processMethod(MethodMod
ifier.java:121)
 ...

To clarify, the ant entry I'm using is as follows:

<iajc sourceroots="${core.java}" destdir="${build.classes}"
 deprecation="true" debug="true" xlintwarnings="true"
 classpathref="build.path" source="1.4" target="1.4" x="noInline"/>
Comment 10 Chris Nappin CLA 2006-05-09 09:50:36 EDT
Hi,

  I've just re-tested with AspectJ 1.5.1a and unfortunately the fault is still present. Is there any chance the priority of this issue can be increased?

At the moment it means that none of the code executed in a Unit test environment can include any AOP code.

  Thanks,

Chris.
Comment 11 Andrew Clement CLA 2006-05-09 12:36:38 EDT
let me give it some kind of priority for 1.5.2 ... not sure what I'll do for it yet tho:

- adding line number info for generated code is a bogus as the code never existed in source....
- adding synthetic attribute to the code may be something we have to look into again, or ... maybe the bridge flag makes sense actually for some of these ...
- asking jblanket to respect the ajsynthetic attribute in addition to the synthetic attribute would be another option...
Comment 12 Chris Nappin CLA 2006-05-11 05:21:01 EDT
Hi, thanks for considering to resolve this issue.

> - adding line number info for generated code is a bogus as the code 
> never existed in source....

I thought the result of your investigation on the Sun javac compiler (comment #4 below) was that it generates "bogus" line numbers if in debug mode, and aspectj should merely do the same?

> - asking jblanket to respect the ajsynthetic attribute in addition to the
> synthetic attribute would be another option...

I have tried out a few other Code Coverage tools and they also suffer from the same problem. Rather than changing every code coverage tool on the market it might be easier to change aspectj?

If you require any further info to help you out, please just let me know.

Thanks,

  Chris Nappin.
Comment 13 Andrew Clement CLA 2006-05-16 07:45:40 EDT
I just committed a change to add blank line number tables for the XXXproceed() method you are hitting and aspectOf/hasAspect methods - we should investigate proper use of synthetic but this is a suitable temporary workaround as we dont have the time to do that investigation right now.  When the dev build is available I will close this bug report.
Comment 14 Andrew Clement CLA 2006-05-16 09:46:34 EDT
dev build is available with the proposed changes in.  There may be other methods that exhibit this problem .. please reopen this if you come across them.
Comment 15 Chris Nappin CLA 2006-05-16 10:17:23 EDT
Thanks, downloading the latest development build that seems to have resolved all our use of Aspects so far.

Do you know when the 1.5.2 release is expected to be available?
Comment 16 Andrew Clement CLA 2006-05-16 10:38:34 EDT
from our plans page :

http://www.eclipse.org/aspectj/plans.php

we are looking at end of June 2006 for 1.5.2