Bug 1013 - GetType() method call cannot be intercepted by a transparent proxy
Summary: GetType() method call cannot be intercepted by a transparent proxy
Status: RESOLVED ANSWERED
Alias: None
Product: Class Libraries
Classification: Mono
Component: mscorlib ()
Version: 2.10.x
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-09-23 04:25 UTC by Alexey Yakovlev
Modified: 2017-09-26 19:31 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Sample code to demonstrate GetType() method interception in transparent proxies. (1.92 KB, text/plain)
2011-09-23 04:25 UTC, Alexey Yakovlev
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description Alexey Yakovlev 2011-09-23 04:25:02 UTC
Created attachment 477 [details]
Sample code to demonstrate GetType() method interception in transparent proxies.

Transparent proxy cannot intercept GetType() method call in Mono.
In Microsoft .NET runtime, it can be intercepted just like any other method:

var intValue = myTransparentProxy.GetValue(); // can be intercepted
var type = myTransparentProxy.GetType(); // cannot be intercepted in Mono

RemotingProxy class in Mono handles GetType() method call by itself,
see mcs\class\corlib\System.Runtime.Remoting.Proxies\RemotingProxy.cs, line 192
in Mono version 2.10.5. But it looks like execution flow doesn't get there
for some reason. 

See the attached sample for the details.
Here is an execution log:

Executed by Microsoft .NET 4 runtime:
-------------------------------------
Method called: Int32 GetValue()
GetValue() returns 0
Method called: System.Type GetType()
GetType() method call intercepted, returning ISample...
GetType() returns ISample

Executed by Mono 2.10.5 runtime:
--------------------------------
Method called: Int32 GetValue()
GetValue() returns 0
GetType() returns System.MarshalByRefObject
Comment 1 Rogier Hofboer 2014-02-26 16:32:32 UTC
See also bug 17325
Comment 2 Rogier Hofboer 2017-03-01 10:02:43 UTC
This is still a problem in mono 4.8.x and in master (5.x.x) with reference sources, because it is caused by the runtime.
Comment 3 Aleksey Kliger 2017-08-10 17:20:31 UTC
This seems more challenging to fix than bug 17325 without causing performance regressions in all uses of System.Object.GetType().

As it happens System.Object.GetType() is a little bit special in that Mono's JIT tries to replace calls to that method by a direct access to a System.Type that's stored in the vtable.  When we see IL for a call to System.Object.GetType, the doesn't bother emitting a call, it just emits straight line code to load the object vtable and load the stored System.Type.   This happens both for real objects and for transparent proxies. Pretty much the only time we call the real System.Object.GetType method is when working indirectly (for example using reflection).

I am really hesitant to add any branching to the JITted code because it will make GetType slower for all objects, even ones which don't care about remoting at all.  And AFAICT I don't know at JITting time whether the object is going to be a normal object or a proxy (the object might be a method argument, for example).
Comment 4 Alexey Yakovlev 2017-08-10 19:56:18 UTC
Thanks for the explanation Aleksey!

As far as I remember, I was intercepting the GetType method
just to make sure it's never invoked via remoting just to return
the information already known by the caller (the proxied type).

So, for my use case the fix for bug 17325 is just fine.
Comment 5 Rogier Hofboer 2017-08-11 14:42:01 UTC
Same here, the fix for bug 17325 does the job.
Comment 6 Aleksey Kliger 2017-09-26 19:31:08 UTC
Closing this.  We can revisit in the future, if necessary.