Fixed: SymWriter COM object is not released on exception #955
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The Problem
Accessing a PDB file edited with Cecil randomly produces errors about the file being locked.
Problem observed when being used in coverlet:
coverlet-coverage/coverlet#1471
This is caused by an exclusive file handle held by the SymWriter COM object.
It is not released before the COM object is released.
In normal execution,
NativePdbWriter.Write
callsSymWriter.Close
at the end,which in turn calls
Marshal.ReleaseComObject
, releasing the object and file handle.But if an exception causes
NativePdbWriter.Write
to never be called, there is no call toSymWriter.Close
,which in turn means
Marshal.ReleaseComObject
is left uncalled.The garbage collector will eventually destroy the object and thereby release the COM object, but that happens non-deterministically. The result was random file access issues with the PDB file.
The Solution
Luckily
NativePdbWriter
isIDisposable
. I added a call towriter.Close
to theDispose
. But nowClose
could be called twice, so I had to add a boolean to SymWriter to avoid releasing the resources twice.