CodeAccessSecurityEngine exception
Two of my users (out of several thousand) have run into a weird exception when my app starts. I haven't been able to find any useful information about it via Google, MSDN or Reflector.
In case you want to copy paste this stuff, here's it written out:
External component has thrown an exception.
Stack trace:
at System.Security.CodeAccessSecurityEngine.CheckNReturnSO(PermissionToken 开发者_开发技巧permToken, CodeAccessPermission demand, StackCrawlMark& stackMark, Int32 unrestrictedOverride, Int32 create)
at System.Security.SecurityRuntime.Assert(PermissionSet permSet, StackCrawlMark& stackMark)
at System.Security.PermissionSet.Assert()
at System.Windows.Forms.WindowsFormsSynchronizationContext.InstallIfNeeded()
at System.Winfows.Forms.Control..ctor(Boolean autoInstallSyncContext)
.....
at GrasshopperPlugin.GrasshopperPlugin.OnLoadPlugIn() //This is the first call to my assembly.
at RhDN_NativePlugInBase<CRhinoUtilityPlugIn,RMA::Rhino::MRhinoUtilityPlugIn>.OnLoadPlugIn() //This is the C++/CLI mixed mode SDK that loads my .NET assembly.
What does it mean? Why does it happen? How can I fix/detect this?
I used ILSpy to check the code for WindowsFormsSynchronizationContext.InstallIfNeeded
.
It adds the following permissionset:
new PermissionSet(PermissionState.Unrestricted).Assert();
And then invoke
AsyncOperationManager.SynchronizationContext = new WindowsFormsSynchronizationContext();
which has the following attribute on the setter:
[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
If I understand the security model properly you have to make sure the the users are allowed to run in the "FullTrust" mode.
Just some hints, it isn't crystal from the stack trace. The code that fails lives inside the CLR and is written in C++, the reason you get an imperfect stack trace. First thing to do is take a look at the Output window, odds are good that you see a "first chance" exception notification. Maybe for 0xc0000005, an access violation exception. You can then get more insight by enabling unmanaged code debugging (Project + Properties, Debug tab), enabling the Microsoft symbol server (Tools + Options, Debugging), then ticking the Thrown boxes in Debug + Exceptions so that the debugger will stop on the unmanaged exception. There won't be any code to look at but the stack trace might reveal a hint.
Failing that, it helps to reason about what's going wrong. The code that fails walks the stack, looking for stack frames to verify that the code that calls the method has proper access rights. This code is liable to fail when the stack is corrupted. This is very rare, managed code doesn't corrupt the stack. Problem is: not all of your code is managed. The one that sticks out is RhDN_NativePlugInBase<>.OnLoadPlugIn(). Written in C++/CLI so plenty of odds for something like a stack buffer overflow. Could be something silly like a plugin path that's too long, more than 259 characters. C++ code often takes a nosedive on that.
Another very strong hint that this function corrupts the stack is the stack trace itself. It stops too soon, not showing who called OnLoadPlugin. This is almost certainly the troublemaker. Fixing it is going to be unpleasant, you'll need the source code for this library and debug the C++/CLI code. Ditching the library perhaps ought to be high on your list.
精彩评论