[2020-02] [cominterop] Add coop handle enter/return on native CCW methods (#21366)mono-6.12.0.163
commitb8d7525156acaecf311ba468147caa74d8c190f6
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Mon, 13 Dec 2021 19:40:18 +0000 (13 14:40 -0500)
committerGitHub <noreply@github.com>
Mon, 13 Dec 2021 19:40:18 +0000 (13 14:40 -0500)
tree3696356cba1dbe82e9c8020f77ea07671ad6dbaa
parent2ca650f1f625150c325a26927ecd66d79e09f995
[2020-02] [cominterop] Add coop handle enter/return on native CCW methods  (#21366)

* [tests] Add CCW GetIUnknownForObject leak test

* [cominterop] Add coop handle enter/return on native CCW methods

The CCW methods for IUnknown (and in principle IDispatch - except they all have
trivial bodies) are native C code in the runtime that may allocate coop
handles.  Add a coop handle frame around the entire call in order to make sure
they're cleaned up and don't retain a reference.

This helps fix managed object leaks with code like:

```
   var o  = new SomeClass();
   var pUnk = Marshal.GetIUnknownForObject(o);
   int c = Marshal.Release(pUnk);
   o = null;
```

Which retains a reference to the `SomeClass` instance that won't be collected
until the thread dies, despite cleaning up the IUnknown refcount. The underling
ccw addref/release methods leak coop handles on the thread.

This is not an issue when the CCW calls some managed method because there are
no coop handles there until some icall (at which point it will set up the
coop handle stack properly).

Co-authored-by: Aleksey Kliger <alklig@microsoft.com>
mono/metadata/cominterop.c
mono/tests/cominterop.cs