Quantcast
Channel: CSS SQL Server Engineers
Viewing all articles
Browse latest Browse all 339

SQL CLR assembly fails verification with “Unable to resolve token”

$
0
0

Recently we worked with a customer has an SQL CLR assembly. This customer decided to upgrade from SQL Server 2008 R2 to SQL Server 2012. But this assembly failed to register with SQL Server and he received the following error:
Msg 6218, Level 16, State 2, Line 11
CREATE ASSEMBLY for assembly 'test3.5' failed because assembly 'test3.5' failed verification. Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database. CLR Verifier error messages if any will follow this message [ : Test.Test::my_func][mdToken=0x6000001][offset 0x00000000] Unable to resolve token.

First of all, SQL Server 2008 R2 and SQL 2012 use different versions of CLR. SQL 2008 R2 and below uses CLR 2.0/3.5 but SQL 2012 was upgraded to use CLR 4.0 and above.
What's interesting for this customer is that if they compile the assembly using 4.0 compiler, then they could register the assembly by using CREATE ASSEMBLY.
When we compared the IL generated, there is just one difference dealing with a local variable.
For the assembly compiled for 2.0/3.5, you see ".locals init ([0] void& pinned pData)". But for the assembly compiled for 4.0, you see ".locals init ([0] native int& pinned pData)". See a screenshot below with ildasm:
IL generated by 2.0 compiler


IL generated by 4.0 compiler



The IL in question is generated for the code like fixed (void* pData = &buf[1024]). Basically, the intention is to pin the memory for native call.

Cause

There are two changes in CLR that cause CREATE ASSEMBLY to fail. First, CLR 4.0 compiler no longer generate IL "void& pinned" for code like fixed (void* pData = &buf[1024]). Instead, it generates IL like .locals init ([0] native int& pinned pData). Additionally, CLR 4.0 peverify code is updated and no longer recognize that particular IL generated by CLR 2.0 compiler. When you CREATE ASSEMBLY in SQL Server, it has to do peverify to ensure the assembly passes verification. In this case, SQL 2012 uses 4.0 peverify code to verify the assembly compiled with 2.0 compiler. Therefore, it fails.

Solution

There are two solutions for this.
First option is to compile your assembly using CLR 4.0 compiler targeting 4.0 framework. This should be the best option because SQL 2012 uses CLR 4.0.
If you need your assembly to continue to target 2.0/3.5 framework, you can use 4.0 compiler but link 2.0 version of mscorlib.dll. Here is an example command.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /nostdlib+ /noconfig /r:c:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll -unsafe -optimize -debug:pdbonly -target:library -out:test.dll test.cs

Repro

Step 1 Save the following code into test.cs

using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.Win32;
namespace Test
{
unsafepublicclassTest
{
unsafepublicdelegatevoid my_Delegate(ushort comp,
ushort func,
void* ptr,
uint length);
publicstatic my_Delegate delegate1;

uint dataLength = 0;
publicvoid my_func (String objectId,
uint component,
uint method,
ushort level,
String caption,
uint offset,
int length,
byte[] buf)
{
fixed (void* pData = &buf[1024])
{

delegate1((ushort)component,
(ushort)method,
pData,
dataLength);
}
}
}
}

Step 2 Compile the assembly

Compile using the following command
C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe -unsafe -optimize -debug:pdbonly -target:library -out:test3.5.dll test.cs

Step 3: CREATE ASSEMBLY

If you "create assembly asem from 'C:\repro2\test3.5.dll' with permission_set=unsafe", you will receive the above error.

Step 4: solution and workaround

But the following two commands won't result in errors
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe -unsafe -optimize -debug:pdbonly -target:library -out:test4.0.dll test.cs
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /nostdlib+ /noconfig /r:c:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll -unsafe -optimize -debug:pdbonly -target:library -out:test.dll test.cs

Jack Li | Senior Escalation Engineer | Microsoft SQL Server Support


Viewing all articles
Browse latest Browse all 339

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>