Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

Use GC.KeepAlive() to prevent early collection of method parameters #719

Description

@jonpryor

@brendanzagaeski has diagnosed an issue wherein object references are collected when we think they shouldn't be.

Consider the following generator-emitted binding code:

publicunsafeboolHideSoftInputFromWindow(Android.OS.IBinder?windowToken,[global::Android.Runtime.GeneratedEnum]Android.Views.InputMethods.HideSoftInputFlagsflags){conststring__id="hideSoftInputFromWindow.(Landroid/os/IBinder;I)Z";try{JniArgumentValue*__args=stackallocJniArgumentValue[2];/* 1 */__args[0]=newJniArgumentValue((windowToken==null)?IntPtr.Zero:((global::Java.Lang.Object)windowToken).Handle);/* 2 */__args[1]=newJniArgumentValue((int)flags);/* 3 */var__rm=_members.InstanceMethods.InvokeAbstractBooleanMethod(__id,this,__args);return__rm;}finally{}}

Depending on "various factors", it is possible that Mono's GC will decide that windowToken -- used on line (1) -- is eligible for collection on line (2), when it must be kept alive until after line (3) completes execution.

If windowTokenisn't kept alive, then it could be finalized before/during the InvokeAbstractBooleanMethod() invocation, which could invalidate/change windowToken.Handle, and cause lots of head scratching, confusion, and app crashes.

The fix? We need to emit a GC.KeepAlive() for all reference types until after the Invoke* invocation has completed:

publicunsafeboolHideSoftInputFromWindow(Android.OS.IBinder?windowToken,[global::Android.Runtime.GeneratedEnum]Android.Views.InputMethods.HideSoftInputFlagsflags){conststring__id="hideSoftInputFromWindow.(Landroid/os/IBinder;I)Z";try{JniArgumentValue*__args=stackallocJniArgumentValue[2];__args[0]=newJniArgumentValue((windowToken==null)?IntPtr.Zero:((global::Java.Lang.Object)windowToken).Handle);__args[1]=newJniArgumentValue((int)flags);var__rm=_members.InstanceMethods.InvokeAbstractBooleanMethod(__id,this,__args);/* FIX */global::System.GC.KeepAlive(windowToken);return__rm;}finally{}}

Metadata

Metadata

Assignees

Labels

bugComponent does not function as intendedgeneratorIssues binding a Java library (generator, class-parse, etc.)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions