Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppDomain.CurrentDomain.Evidence throws SerializationException

Tags:

c#

.net

I got a strange error when running my test cases using ReSharper (8.2.2) with VS 2013.

A simplified test case that demos the problem only contains two lines of code:

CallContext.LogicalSetData("mydata", new ActivityStack());
var evidence = AppDomain.CurrentDomain.Evidence;

where ActivityStack is a custom type that is serializable. The second line would throw an exception when the test case is run via ReSharper:

System.Runtime.Serialization.SerializationException was unhandled by user code
  HResult=-2146233076
  Message=Type is not resolved for member 'CSG.Framework.Operations.ActivityStack,CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223'.
  Source=mscorlib
  StackTrace:
       at System.AppDomain.get_Evidence()
       at System.AppDomain.get_Evidence()
       at CSG.Framework.Utilities.AppDomainLauncher`1..ctor(String appDomainName) in d:\Work\Git\Framework\Src\Library\Framework\Utilities\AppDomainLauncher.cs:line 40
       at CSG.Framework.UnitTest.AppDomainLauncherTests.LaunchClassFromCallingAssembly() in d:\Work\Git\Framework\Src\Library\Framework.UnitTest\Utilities\AppDomainLauncherTests.cs:line 52
  InnerException: 

Even though the current AppDomain appears to have the correct path on BaseDirectory where the assembly containing the type can be found, CLR appears to be still using the ReSharper bin path to probe for the assembly according to Fusion log. The problem would go away if I copy the assembly to ReSharper bin folder, but I don't think that's the right solution. I tried to subscribe to AssemblyResolve event on current AppDomain, but the handler did not get called.

Fusion log:

*** Assembly Binder Log Entry  (1/23/2015 @ 12:28:54 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:     C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\JetBrains\ReSharper\v8.2.Qiwabic\Bin\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = JetBrains.ReSharper.TaskRunner.CLR45.x64.exe Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files (x86)\JetBrains\ReSharper\v8.2.Qiwabic\Bin\JetBrains.ReSharper.TaskRunner.CLR45.x64.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: CSG.Framework, Version=15.2.0.0, Culture=neutral, PublicKeyToken=e7ab1d859f54b223
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework/CSG.Framework.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/JetBrains/ReSharper/v8.2.Qiwabic/Bin/CSG.Framework/CSG.Framework.EXE.
LOG: All probing URLs attempted and failed.
like image 920
wqiu Avatar asked Jan 09 '23 01:01

wqiu


1 Answers

This linke (https://msdn.microsoft.com/en-us/library/dn458353(v=vs.110).aspx) explains the root cause.

There are two app domains involved: the default app domain (ReSharper runner), and the current app domain (test case). When AppDomain.Evidence is executed in the current app domain:

  • It looks for evidence for the current app domain.
  • It tries to calculate the evidence for the current app domain based on the current domain.
  • The call to get evidence for the current domain triggers a cross-app domain call from the current app domain to the default app domain.
  • As part of the cross-app domain contract in the .NET Framework, the contents of the logical call context also have to be marshaled across app domain boundaries.

Because the type (ActivityStack) that are in the logical call context cannot be resolved in the default app domain, an exception is thrown.

like image 120
wqiu Avatar answered Jan 11 '23 21:01

wqiu