Options

VerificationException only when profiling

Windows 7 x86
Visual Studio 2010
C#
Ants Performance Profiler 6.2.0.13 Standard

I'm looking for help in nailing down a problem that crops up only when I attempt to profile my application.

I have a C# console application. It had always run and profiled just fine until I brought a third party C# DLL into the build. My application continued to run without issues, but whenever I attempted to profile it I'd get a System.Security.VerificationException at the point where I attempt to create an instance of a class or struct from the third party DLL (the top level exception is a TypeInitializationException).

All assemblies are built for version 2.0 of the CLR. The third party DLL verifies type-safe with the 2.0 and 4.0 versions of peverify.

I tried some additional experiments with the third party DLL and found that

1. Creating an instance of a struct throws TypeInitialization and Verification exceptions. A parameterless struct constructor does not.
2. Assembly.LoadFile on the third party DLL does not throw an exception.
3. Calling a static method in the third party DLL does not throw an exception.
4. Accessing a const in the third party DLL does not throw an exception.

Per another post that I saw somewhere, I removed line-level profiling and that avoids the exception. But I lose line-level profiling.

The assemblies referenced by the third party DLL are 2.0.0.0 versions of

mscorlib
System
System.XML

I've been reading about security and such, and I've been poking and prodding the application from a variety of different angles, but because this is happening in the context of the profiler, I thought I'd ask for sage advice here.

Any help would be appreciated. I feel a bit naked without the ability to profile my code line by line.

Comments

  • Options
    I think the problem has something to do with the changes in code access policy between the 2.0 and 4.0 runtime. If you have assemblies that use the SecurityPermission attribute as it existed in 2.0, and run them in 4.0, you can end up with a VerificationException. The only way I know to fix this is to change the third-party DLL to take out the attribute and recompile it. This may not be possible.

    An easier option may be to change the app config file so the supportedRuntime is 2.0. I had a similar issue with ASP .NET here:
    http://www.red-gate.com/MessageBoard/vi ... hp?t=11404
  • Options
    Thanks for the reply, Brian. The new DLL does have SecurityPermission attributes, but taking them out didn't change the behavior. It also has CLSCompliant attributes, which I have not touched as they would be a little more work to remove.

    Everything I have is .NET 2.0, including the new DLL. Is there anything special that I can do with the profiler to get it to operate exclusively in that space? In the thread you linked, there's mention of something that can be done with a test web server, but I'm working with a console application. I can find no setting in the profiler user interface that suggests a solution.
  • Options
    I probably should have mentioned a somewhat unusual usage pattern from the start: I'm dynamically loading an assembly (Assembly.LoadFrom), and that assembly is the only thing in the application referencing the third party DLL.

    I have another windows application that directly links to the third party DLL, and that profiles just fine. So I created a direct link from the console application to the third party DLL and now the console application profiles just fine. No actual calls to the third party DLL are needed; just the reference.

    Do I need to stick with this workaround or is there some way for me to tell the profiler that this situation exists? Is there a particular usage pattern for dynamically loading assemblies that I should follow in order to make the profiler happy?
  • Options
    I continued to hammer away at this and it seems that the dynamic load has nothing to do with the problem. I wouldn't put money on that claim because I could swear I could control failures by twiddling references in Visual Studio - but after more testing, it seems that it's entirely an issue of assembly attributes.

    There were two (of four) assembly attributes that needed to be removed if the profiler was going to run.

    [assembly: PermissionSet(SecurityAction.RequestOptional, Name = "Nothing")]
    and
    [assembly: FileIOPermission(SecurityAction.RequestOptional, Unrestricted = true)]

    Once removed, the process ran normally while being profiled.

    SecurityAction.RequestOptional is listed as being obsolete, but there are two other assembly attributes in the same DLLs that use obsolete SecurityActions that do not block the profiler:

    [assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
    and
    [assembly: SecurityPermission(SecurityAction.RequestRefuse, UnmanagedCode = true)]

    I haven't tried twiddling with this stuff because I don't have a clue what it does.
  • Options
    Thanks for your follow up. I'm happy that pointing you in the direction of code access security was at least a good start. I'm no expert on the subject but I'd imagine any restriction on unmanaged code and file I/O would cause the Profiler core component to break.

    AFAIK it never used to be a problem before .NET 4 came out, though. I guess it's trying to map the old CASPOL scheme onto the new .NET 4 one and it's causing incompatibilities.
Sign In or Register to comment.