Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential Exponential Behavior in Obligation Tracking in Must Call Inference #6566

Closed
iamsanjaymalakar opened this issue May 1, 2024 · 0 comments · Fixed by #6567
Closed
Assignees
Labels

Comments

@iamsanjaymalakar
Copy link
Member

Description

During the investigation of what was initially suspected to be a non-termination bug in the url90b6689baa_adsonrocha_PD321_tgz-pJ8-MyFuzzyLiteClassJ8 project from the NJR dataset, it was discovered that the issue may actually be exponential growth in complexity rather than non-termination. This behavior occurs due to an unchecked accumulation of obligations to track across multiple control-flow paths when the bailout check MustCallConsistencyAnalyzer::shouldTrackInvocationResult is absent.

Steps to Reproduce

  • Run the application on the url90b6689baa_adsonrocha_PD321_tgz-pJ8-MyFuzzyLiteClassJ8 project from the NJR dataset, wit h resourceleak inference enabled.
    Source: url90b6689baa_adsonrocha_PD321_tgz-pJ8-MyFuzzyLiteClassJ8.zip
  • Execute the reproducing unit test tests/ainfer-resourceleak/non-annotated/FuzzyEngine.java within the ainfer-resourceleak test suite, noting the out-of-memory error that occurs without the proposed modifications, highlighting the unchecked growth in resource consumption.

Fix

The MustCallConsistencyAnalyzer has a bail-out check before tracking obligations using the shouldTrackInvocationResult method. The original method was designed primarily for MustCall consistency checks and did not accommodate the unique requirements of resource leak inference.

The original method does not track the invocation result in these cases:

  • Constructor Calls: Skips tracking for this() or super() constructor calls.
  • MustCallAlias Annotations: Omits tracking when the method’s return type is MustCallAlias and corresponds to an owning field.
  • Non-owning Return Types: Avoids tracking for methods annotated with NotOwning or methods that have no return type.

For example, consider the following code snippet:

@InheritableMustCall("a")
private class MCASuperClass {
  final @Owning Foo f;

  @MustCallAlias MCASuperClass(@MustCallAlias Foo foo) {
    this.f = foo;
  }

  public void a() {
    f.a();
  }
}

private class MCASuperCall extends MCASuperClass {
  MCASuperCall(Foo foo) {
    super(foo);
  }
}

In this scenario, if obligations for the super(foo) call are not tracked, then the must-call inference cannot infer that the parameter Foo foo and the constructor are resource aliases. This failure results in the inability to infer the @MustCallAlias annotation correctly for the MCASuperCall, leading to potential resource management issues.

@MustCallAlias MCASuperCall(@MustCallAlias Foo foo) {
  super(foo);
}

To rectify this, a new parameter isMustCallInference was added to the shouldTrackInvocationResult method. This parameter allows the method to adapt its behavior based on the context—skipping tracking where safe in general cases but enforcing it in resource leak scenarios to ensure accurate management of obligations.

CF Invocation Environment

  • Ubuntu 20.04
  • JDK 11
  • Flags
    -processor org.checkerframework.checker.resourceleak.ResourceLeakChecker \
    -Adetailedmsgtext \
    -Aajava=$PROJECT_PATH/wpi-out \
    -Ainfer=ajava \
    -Awarns \
    -AshowPrefixInWarningMessages \
    -AdisableReturnsReceiver \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant