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

Incorrect programId passed to Boogie causes memory leak in LSP server #1863

Closed
cpitclaudel opened this issue Feb 26, 2022 · 0 comments
Closed
Labels
area: performance Performance issues kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: language server Support for LSP in Dafny (server part; client is in ide-vscode repo)

Comments

@cpitclaudel
Copy link
Member

Boogie accepts a programId along with each program in ExecutionEngine.InferAndVerify. This ID is used as a key to partition a cache of recent parses:

https://github.com/boogie-org/boogie/blob/ce03249fa06a7442df96352bb55e1bfba3e30365/Source/ExecutionEngine/ExecutionEngine.cs#L253-L257

A reasonable choice of key, for example, is the path of the current program. Alternatively, if there is only one program being verified, using null is also reasonable; in that case Boogie uses a default string (https://github.com/boogie-org/boogie/blob/ce03249fa06a7442df96352bb55e1bfba3e30365/Source/ExecutionEngine/ExecutionEngine.cs#L318-L321). This is what the Dafny CLI does:

var ev = ProcessFiles(new List<DafnyFile> { f }, new List<string>().AsReadOnly(), reporter, lookForSnapshots, f.FilePath);

if (programId == null) {
programId = "main_program_id";
}
programId += "_" + moduleName;

The legacy DafnyServer used by Emacs uses just a module name, because it can't operate on more than one file at a time, so the file name part isn't needed:

switch (ExecutionEngine.InferAndVerify(boogieProgram, new PipelineStatistics(), "ServerProgram_" + moduleName, null, DateTime.UtcNow.Ticks.ToString())) {

The LSP server does something different:

var uniqueId = Guid.NewGuid().ToString();
using (cancellationToken.Register(() => CancelVerification(uniqueId))) {
try {
var statistics = new PipelineStatistics();
var outcome = ExecutionEngine.InferAndVerify(program, statistics, uniqueId, null, uniqueId);

The test generator does the same thing, which is equally wrong, I think:

var log = Utils.CaptureConsoleOutput(
() => ExecutionEngine.InferAndVerify(program,
new PipelineStatistics(), uniqueId,
_ => { }, uniqueId));

In both cases one new program entry is created in the cache every time Boogie is queries. The cache's default expiration policy is a 10-minutes window, so for 10 minutes memory usage just grows.

The fix is to pass the program name instead of a freshly created unique string as the programId. I will open a PR soon.

@cpitclaudel cpitclaudel added kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label area: performance Performance issues part: language server Support for LSP in Dafny (server part; client is in ide-vscode repo) labels Feb 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: performance Performance issues kind: bug Crashes, unsoundness, incorrect output, etc. If possible, add a `part:` label part: language server Support for LSP in Dafny (server part; client is in ide-vscode repo)
Projects
None yet
Development

No branches or pull requests

1 participant