System.Security.VerificationException: Operation could destabilize the runtime. (Subsonic 2.2)
Asked Answered
F

2

9

I recently tried to upgrade a .net 2.0 project which had its DAL generated by SubSonic 2.2 to .NET 4.0 under Visual Studio 2010.

The projects converted without error but now I am getting a rather vile error message when I try to launch it.

System.Security.VerificationException: Operation could destabilize the runtime.  

at SubSonic.DataProvider.ApplyConfig(NameValueCollection config, Boolean& parameterValue, String configName) in C:\Documents and Settings\Desktop\4.0 Production\rel_1.0\server\Server.DAL\Server.DAL.SubSonic\DataProviders\DataProvider.cs:line 955
   at SubSonic.DataProvider.Initialize(String name, NameValueCollection config) in C:\Documents and Settings\Desktop\4.0 Production\rel_1.0\server\Server.DAL\Server.DAL.SubSonic\DataProviders\DataProvider.cs:line 916
   at System.Web.Configuration.ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type providerType)

The code where it is throwing the exception:

    ApplyConfig(config, ref extractClassNameFromSPName, ConfigurationPropertyName.EXTRACT_CLASS_NAME_FROM_SP_NAME);

    private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref bool parameterValue, string configName)
    {
        if(config[configName] != null)
        {
            parameterValue = Convert.ToBoolean(config[configName]);
        }
    }

It performs similar calls to here, the only difference being it is strictly a string and not a boolean it is manipulating.

private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref string parameterValue, string configName)
{
    if(config[configName] != null)
    {
        parameterValue = config[configName];
    }
}

config is defined as a System.Collections.Specialized.NameValueCollection with 3 keys generateNullableProperties, connectionStringName, generatedNamespace extractClassNameFromSPName == false

EDIT1: The code that kicks off the error is in the Application_Start() method of the Global.asax

System.Data.SqlClient.SqlDependency.Start(SystemSetting.Schema.Provider.DefaultConnectionString);

EDIT2: The error bubbles out to thowing a targetinvocation error referening my web.config

<SubSonicService defaultProvider="appPlan">
    <providers>
        <clear/>
        <add name="appPlan" type="SubSonic.SqlDataProvider, appPlan.Server.DAL.SubSonic" generateNullableProperties="false" connectionStringName="appPlan" generatedNamespace="appPlan.Server.DAL"/>
    </providers>
</SubSonicService>

has anybody else ever run across such an issue? I could upgrade to SubSonic3.x but it would be a much greater undertaking I believe.

thanks.

Featherweight answered 4/3, 2011 at 20:54 Comment(4)
I've upgraded a few websites that use SubSonic 2.0.3 (w/lots of customizations) from 2.0 -> 3.5 -> 4.0 without any problems. I did strip out some of the providers I never, since I had problems with them not supporting x64.Bloat
I stripped out Oracle, MySql and SqlLite thinking there was maybe a conflict there but I get the same issue.Featherweight
The config system uses reflection quite heavily. When the property is accessed it seems that some code of the configured provider Jited. At this point the Runtime checks the generated code and says to you: Nope this type is a bad one. To find the root cause you would need to have a look with Reflector at SubSonic.SqlDataProvider.Nympho
If you have .Net 4.5 installed (which installs over .Net 4.0) then this might be related to a bug involving the .Net 4.5 framework & trust levels with 3rd party & framework dlls. If you're still using the SecurityRules work around you may want to check out this hotfix to see if it applies to you & fixes the problem (it did for my team) support.microsoft.com/kb/2748645Barye
S
1

Does this fix the problem?

private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref bool parameterValue, string configName)
{
    if(config[configName] != null)
    {
        string val = config[configName];
        parameterValue = Convert.ToBoolean(val);
    }
}

If not, then try

string val = config[configName];
if (val.ToLower() == "false")
    parameterValue = false;
else
    parameterValue = true;

There may be 2 reasons why the original code fails. First, earlier version of .NET (probably 1.1) had some type issue. I don't know what exactly, but I suspect it might have failed to identify the type of the value passed straight from the NameValueCollection into ToBoolean. The second possibility is that the value is not "true" or "false", but something else. Again, these 2 may or may not be the reason. I can't know for sure because I don't have SubSonic 2.2.

Song answered 11/3, 2011 at 3:34 Comment(1)
I tried this but the error is actually occuring at: if(config[configName] != null) and not at the boolean conversion. I've cheated until I can get it figured out and added this to the AssemblyInfo.cs file:: [assembly: SecurityRules(SecurityRuleSet.Level1, SkipVerificationInFullTrust = true)] I found mention of a .net4 vs .net2 transparency issue with Unreliable/unsafe code and the security rules of .net4.0 adding the line to the file tells it to use the 2.0 rules (from what I can tell)Featherweight
S
3

I have seen this exception before when generating assemblies directly from hand-crafted IL. The .NET runtime verifies the raw instructions in an assembly for correctness, especially when loading the assembly into restricted contexts. For example, there is a check to ensure that the required number of arguments are loaded onto the call-stack before executing a method.

An assembly can still be loaded even if verification fails; but it can only be run in full trust. In partial trust scenarios you get this "operation could destabilize the runtime" error. The reason being that the runtime cannot guarantee safe operation of assemblies in partial trust if they do not "behave correctly".

You can manually check an assembly using the PEVERIFY tool (available via a Visual Studio Command Prompt). Try verifying all of the referenced assemblies to see what is reported. I suspect there was a change in the verification rules between .NET 2.0 and .NET 4.0 that is now causing verification to fail for one of the SubSonic 2.2 assemblies.

Your cheat you mention in response to Fun Mun Pieng also suggests verification is the issue.

Sangsanger answered 14/3, 2011 at 15:22 Comment(0)
S
1

Does this fix the problem?

private static void ApplyConfig(System.Collections.Specialized.NameValueCollection config, ref bool parameterValue, string configName)
{
    if(config[configName] != null)
    {
        string val = config[configName];
        parameterValue = Convert.ToBoolean(val);
    }
}

If not, then try

string val = config[configName];
if (val.ToLower() == "false")
    parameterValue = false;
else
    parameterValue = true;

There may be 2 reasons why the original code fails. First, earlier version of .NET (probably 1.1) had some type issue. I don't know what exactly, but I suspect it might have failed to identify the type of the value passed straight from the NameValueCollection into ToBoolean. The second possibility is that the value is not "true" or "false", but something else. Again, these 2 may or may not be the reason. I can't know for sure because I don't have SubSonic 2.2.

Song answered 11/3, 2011 at 3:34 Comment(1)
I tried this but the error is actually occuring at: if(config[configName] != null) and not at the boolean conversion. I've cheated until I can get it figured out and added this to the AssemblyInfo.cs file:: [assembly: SecurityRules(SecurityRuleSet.Level1, SkipVerificationInFullTrust = true)] I found mention of a .net4 vs .net2 transparency issue with Unreliable/unsafe code and the security rules of .net4.0 adding the line to the file tells it to use the 2.0 rules (from what I can tell)Featherweight

© 2022 - 2024 — McMap. All rights reserved.