Skip to content

Commit 50292e7

Browse files
Fixed: SymWriter COM object is not released on exception (#955)
* Fixed: SymWriter COM object is not released on exception The Problem: Problem observed when being used in coverlet: coverlet-coverage/coverlet#1471 If an exception caused `NativePdbWriter.Write` to never be called, it would not call `SymWriter.Close`, which in turn meant `Marshal.ReleaseComObject` was left uncalled. The garbage collector will eventually destroy the object and thereby release the COM object, but that happens non-deterministically. The COM object is holding to a file handle, which prevents other operations on the written file until it is released. The result was random file access issues. The Solution: Luckily NativePdbWriter is IDisposable. I added a call to `writer.Close` there. But now it could be called twice, so I had to add a boolean to SymWriter to avoid releasing everything twice. * Code style --------- Co-authored-by: Jb Evain <[email protected]>
1 parent 608fac6 commit 50292e7

File tree

2 files changed

+6
-0
lines changed

2 files changed

+6
-0
lines changed

symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ public void Write ()
267267

268268
public void Dispose ()
269269
{
270+
writer.Close ();
270271
}
271272
}
272273

symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static extern int CoCreateInstance (
3030

3131
readonly ISymUnmanagedWriter2 writer;
3232
readonly Collection<ISymUnmanagedDocumentWriter> documents;
33+
bool closed = false;
3334

3435
public SymWriter ()
3536
{
@@ -78,6 +79,10 @@ public void DefineConstant2 (string name, object value, int sigToken)
7879

7980
public void Close ()
8081
{
82+
if (closed)
83+
return;
84+
85+
closed = true;
8186
writer.Close ();
8287
Marshal.ReleaseComObject (writer);
8388

0 commit comments

Comments
 (0)