#132 Unexpected frames result in invalid class files

closed-fixed
nobody
JaCoCo (32)
9
2012-08-01
2012-07-13
Derek
No

I just updated to the latest EclEmma plugin (which includes JaCoCo 0.5.8) and I'm now able to reproduce a severe regression in JaCoCo in both Eclipse and via our builds. In both cases, we get an error that looks like this:
java.lang.ClassFormatError: StackMapTable format error: bad verification type
and then at some point the JVM will crash.

Discussion

1 2 3 4 > >> (Page 1 of 4)
  • Derek
    Derek
    2012-07-13

    • priority: 5 --> 9
     
  • Derek
    Derek
    2012-07-13

    This issue does not reproduce with JaCoCo 0.5.7. Something appears to have regressed.

     
  • Derek
    Derek
    2012-07-13

    Sorry, one more detail: we are running on the latest Java 6.

     
  • Can you please attach an class file that where you get the StackMapTable error with JaCoCo?

    Thanks,
    -marc

     
  • Derek
    Derek
    2012-07-14

    problematic class?

     
    Attachments
  • Derek
    Derek
    2012-07-14

    I've attached the classfile I believe is hitting issues. Unfortunately it's in the middle of some fairly complicated and intertwined code so I'm not sure if you can do much with it without the supporting classfiles.

     
  • Yes, I can confirm that JaCoCo seems to produce an invalid stackmap table for this class. I'll investigate. Thx!

     
  • Hi,

    many thanks for providing the class file! With this I was actually able to identify the source of the problem: In certain situations JaCoCo adds a stackmap frame where the original code already has an stackmap frame. Two consecutive identical frames cause causes ASM to produce invalid class files. This has to be fixed in JaCoCo.

    I would would like to create an integration test first for this scenario. May I ask you to add the source code of the following method (code in lines 1157 to 1191)? This would help to create an minimal reproducer.

    public static org.apache.commons.lang3.tuple.Pair getNewMetricTokenFor(java.lang.String, java.lang.String, com.palantir.finance.commons.language.HHLangRefactorModule, java.lang.Class, java.lang.Class, java.util.List, com.palantir.finance.commons.metric.context.EvaluationContext, java.lang.Class);

    Best regards,
    -marc

     
  • Derek
    Derek
    2012-07-17

    Here ya go:

    public static Pair<String, UUID> getNewMetricTokenFor(@CheckForNull String oldToken, String documentVersion,
    @CheckForNull HHLangRefactorModule refactorModule, @CheckForNull Class<?> inputType, @CheckForNull Class<?> outputType,
    @CheckForNull List<Expression> parameters, @CheckForNull EvaluationContext variablesContext, @CheckForNull Class<?> classBeingConverted) {
    if (oldToken == null) {
    return null;
    }
    if (Version.CURRENT_VERSION.equals(Version.valueOf(documentVersion))) {
    return null;
    }

    Map<Version, Multimap<String, Triple<String, Class<?>, UUID>>> refactorMap = refactorModule == null ? HHLangUtils.getRefactorModule().getMetricTokenMap() : refactorModule.getMetricTokenMap();
    String oldTokenLowerCase = oldToken.toLowerCase(Locale.US);
    for(Entry<Version, Multimap<String, Triple<String, Class<?>, UUID>>> entry : refactorMap.entrySet()) {
    Version refactorVersion = entry.getKey();
    if(refactorVersion.compareTo(Version.valueOf(documentVersion)) >= 0 && entry.getValue().containsKey(oldTokenLowerCase)) {
    for (Triple<String, Class<?>, UUID> entryValue : entry.getValue().get(oldTokenLowerCase)) {
    Class<?> metricClass = entryValue.getSecondValue();
    if (classBeingConverted != null && !classBeingConverted.equals(metricClass)) {
    continue;
    }
    if (inputType != null || outputType != null || parameters != null) {

    Metric<?, ?> m = MetricOntology.getMetricWithId(entryValue.getThirdValue());
    if (inputType != null && (m == null || !m.getInputType().isAssignableFrom(inputType))) {
    continue;
    }
    if (outputType != null && (m == null || !outputType.isAssignableFrom(m.getOutputType()))) {
    continue;
    }
    if (tooManyParametersExpected(parameters, variablesContext, m, inputType)) {
    continue;
    }
    }
    return Pair.of(entryValue.getFirstValue(), entryValue.getThirdValue());
    }
    }
    }
    return null;
    }

    Please let me know if you need any other information. BTW, what is your expectation for getting out a patched version?

     
  • Derek
    Derek
    2012-07-17

    code snippet

     
    Attachments
1 2 3 4 > >> (Page 1 of 4)