locked
TypeLoadException when loading injected type from mscorlib RRS feed

  • Question

  • I'm trying to inject a class with a single static method into mscorlib at runtime, and then call the method from instrumented methods in other assemblies.

    I can successfully inject instrumentation calls into methods in "MyProg.exe" to Console.WriteLine() so I know that part works fine. My instrumentation has the same signature as one of the overloaded forms of Console.Writeline().

    The approach I'm taking today is....

    When ModuleLoadFinished is called (and module is mscorlib), I use DefineTypeDef to add my class to mscorlib.

    1. Look up the typeDef for System.Object

    mdTypeDef systemObject;
    
    hr = mdImport->FindTypeDefByName(L"System.Object", NULL, &systemObject);
    

     

    2. Call DefineTypeDef as such...
    mdToken implementsNone[] = { mdTokenNil };
    hr = mdEmit->DefineTypeDef(L"MyHelper", tdPublic | tdBeforeFieldInit, systemObject, implementsNone, &tdHelper);
    
    

    3. Call Define Method...
    COR_SIGNATURE sig[] = MY_METHOD_SIG;
    hr = mdEmit->DefineMethod(tdHelper, L"Method", mdPublic | mdStatic | mdHideBySig, sig, sizeof(sig), 0x1d954, miIL | miManaged, &mdMethod);
    
    

    Then in ModuleLoadFinished when another module (MyModule) is called........
    	// Get LocalMsCorLibReference by enumerating the AssemblyReferences until we find the mscorlib one.
    
    	mdTypeRef trLocalHelper;
    	hr = mdEmit->DefineTypeRefByName(LocalMsCorLibReference, L"MyHelper", &trLocalHelper);
    
    	COR_SIGNATURE sig[] = MY_METHOD_SIG;
    	mdMemberRef mrLocalMethod;
    	hr = mdEmit->DefineMemberRef(trLocalInstrumentationHelper, L"Method", sig, sizeof(sig), &mrLocalMethod);
    
    

    (I think) This sets up the TypeRef and MemberRef from the current module back to the type defined in mscorlib.
    However, when I run the program I get a TypeLoadException like this...
    Unhandled Exception: System.TypeLoadException: Could not load type 'MyHelper' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
       at Program.Main(String[] args)
    I've tried messing with the RVA value, and checking type names, etc... If I change the second part of the code to add the typeRef to Console.Writeline instead of my instrumentation code, it runs just fine. So it seems like it's a problem with the metadata definition. Or maybe the verifier is choking on something. JITCompilationStarted is not even being called for my injected method (in mscorlib).
    Any ideas? Thanks in advance for your help.

    Friday, September 2, 2011 9:02 PM

Answers

  • Ok, I think I figured it out. The key (at least in this case) is adding the new type and method metadata in ModuleLoadStarted. Apparently, if you add it in ModuleLoadFinished, it's too late and subsequently not recognized.
    Wednesday, September 7, 2011 1:45 PM

All replies

  •  

    Hi,

     

    Well, mscorlib.dll is an assembly service for .NET Framework. I haven't tried to add any classes to this assembly, and I don't know why need to modify the dll. Why not just created a new library to add your customer classes.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, September 6, 2011 7:08 AM
  • My reasoning for adding to mscorlib was because we instrument mscorlib, and as I understand it, mscorlib cannot have a reference to any other assembly.

    I can probably make this work by adding a dynamic assembly, I'll just have to have two different instrumentation strategies. One for mscorlib and another for everything else.

    Dave Broman suggests on his blog (http://blogs.msdn.com/b/davbr/archive/2010/01/21/writing-a-profiler-for-silverlight-4.aspx) that adding code to mscorlib is an option, so that was the route I was taking.

    Can anyone confirm whether that is possible or not?

    Tuesday, September 6, 2011 12:59 PM
  • Ok, I think I figured it out. The key (at least in this case) is adding the new type and method metadata in ModuleLoadStarted. Apparently, if you add it in ModuleLoadFinished, it's too late and subsequently not recognized.
    Wednesday, September 7, 2011 1:45 PM
  • Following Dave's advice is the right way to go... if you want to instrument inside of mscorlib then injecting the instrumentation helper classes in mscorlib is pretty much the only option.

    -Noah

     

    Thursday, September 8, 2011 6:02 AM
    Moderator