Re: CSharp Premature Garbage Collection

William S Fulton <[email protected]> Wed, 20 Oct 2021 12:47:11 +0100
Newsgroups gmane.comp.programming.swig
Message-ID <CANGqftBeuRw3fm6ejkpp8M=AS-mQUp2gvsk3o4Cs7Lz7HirMvA@mail.gmail.com>
Hi Denver

You can achieve what you want with the following:

%typemap(csout, excode=SWIGEXCODE) void Pet::set_owner {
    $imcall;
    global::System.GC.KeepAlive(this);
    global::System.GC.KeepAlive(person);$excode
  }

which is a modification of the typemap in csharp.swg:

%typemap(csout, excode=SWIGEXCODE) void {
    $imcall;$excode
  }

It is very specific to this function.

I'd consider putting in improved support for this in SWIG, but I don't
believe this is a premature garbage collection issue as HandleRef prevents
this from happening, so I think you should check your assumption, provide
more/exact details of how to replicate with a cutdown example and check
whether the dotnet runtime you are using is perhaps not a standard
implementation.

Note
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.handleref?view=net-5.0
states:

*    Although using HandleRef to keep an object alive for the duration of a
platform invoke call is preferred, you can also use the GC.KeepAlive method
for the same purpose.*

William


On Mon, 18 Oct 2021 at 18:28, Denver Coneybeare via Swig-user <
[email protected]> wrote:

> TL;DR I am experiencing premature garbage collection in the C# SWIG
> wrappers and need help to work around it, probably by inserting calls
> to GC.KeepAlive().
>
> According to the SWIG documentation at
> http://www.swig.org/Doc4.0/CSharp.html#CSharp
>
> > There is no additional 'premature garbage collection prevention
> parameter' as the marshalling of the HandleRef object takes care of
> ensuring a reference to the proxy class is held until the unmanaged call
> completed.
>
> However, it appears that premature garbage collection is indeed an
> issue that needs to be explicitly addressed, as was done with Java.
> We, at Google, are running into this problem sporadically in
> https://github.com/firebase/firebase-unity-sdk, where we "wrap" our
> C++ SDK in C# using SWIG.
>
> Here is an example SWIG file:
>
> %module CSharpPgcppIssue
> struct Person {
> };
> struct Pet {
>   void set_owner(Person person);
> };
>
> When compiled with SWIG 4.0.2 with this command:
>
> swig -c++ -csharp -o CSharpPgcppIssue.cpp -outdir . CSharpPgcppIssue.swig
>
> The following code is generated in Pet.cs:
>
> public void set_owner(Person person) {
>   CSharpPgcppIssuePINVOKE.Pet_set_owner(swigCPtr, Person.getCPtr(person));
>   if (CSharpPgcppIssuePINVOKE.SWIGPendingException.Pending) throw
> CSharpPgcppIssuePINVOKE.SWIGPendingException.Retrieve();
> }
>
> The problem is that both "this" and "person" may become candidates for
> garbage collection at the point when
> CSharpPgcppIssuePINVOKE.Pet_set_owner() enters the C++ code. If the
> garbage collector chooses to collect them at the earliest possible
> point then "swigCPtr" and the pointer returned from
> "Person.getCPtr(person)" would be deleted and the C++ code would,
> therefore, access freed memory. We actually ran into this when
> targeting Android using the "release" compiler configuration in Unity
> 2020.2.2f1 and now I'm trying to fix it.
>
> The easy fix for this is that I came up with is to insert calls to
> GC.KeepAlive() (
> https://docs.microsoft.com/en-us/dotnet/api/system.gc.keepalive)
> as follows:
>
> public void set_owner(Person person) {
>   CSharpPgcppIssuePINVOKE.Pet_set_owner(swigCPtr, Person.getCPtr(person));
>   GC.KeepAlive(this);
>   GC.KeepAlive(person);
>   if (CSharpPgcppIssuePINVOKE.SWIGPendingException.Pending) throw
> CSharpPgcppIssuePINVOKE.SWIGPendingException.Retrieve();
> }
>
> But I can't find a way to inject these necessary calls. Is this
> possible with SWIG typemaps to somehow inject these calls to
> GC.KeepAlive()? Is there another way to prevent premature garbage
> collection in C#?
>
> Thank you in advance for any help you can provide.
>
>
> _______________________________________________
> Swig-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/swig-user
>

_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user