Bad class token

Hi folks

First let me say that all the developers here love ANTS Profiler. Saves us a ton of time measuring performance. Really easy to use. Great product.

I hit an interesting error while profiling our .NET 2.0 desktop app under ANTS Performance Profiler 2.6 build 62. I have a piece of code that basically is something like:
List<Entry> associationsAlphabetical = new List<Entry>(myObject.Associations);

where myObject.Associations is a generic IList of a custom type called Entry. List is obviously System.Collections.Generic.List. Running this code outside the profiler works fine. However, running it under the profiler, I'm receiving the following error:
5/26/2006 2:18:20 PM. Bad class token.

Stack trace is
at MyCompany.MyCollection`1.CopyTo(T[] array, Int32 arrayIndex)
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)

Any ideas?

Comments

  • Brian DonahueBrian Donahue Posts: 6,590 New member
    Hello,

    Thanks a lot for your comments. I suppose that the first thing to ask would be whether or not you're using some kind of code obfuscator? It looks like either these strange accented characters are being added by some sort of code obfuscation or something is going wrong as ANTS Profiler is instrumenting the code.
  • Hi there,

    This sounds very much like a bug that is happening during the instrumentation of your generic class. If possible, could you create a simple C# test app that mimics the same behaviour? If the same crash happens, could you mail your sample to [email protected]?

    Many thanks,

    Tom

    Red Gate Software
  • Brian, the ` character actually comes from the IL itself. For example, the generic IList interface looks like this in IL:
    System.Collections.Generic.IList`1<!T>
    

    In other words, the IL uses that particular character as a way to denote a generic type.

    Tom, I'll see what I can do about getting you a repro case. If I get some free time, I'll give it a try in a testing project.
  • Hi Judah,

    I have knocked up a quick sample that seems to cover all of the features that you describe. It does not cause any problems for ANTS Profiler 2.6. I would be really interested if you could create a small sample for us as we undoubtedly have a subtle bug with some of our handling of generic lists.

    Thanks,

    Tom Harris

    Red Gate Software
  • Hi guys

    I'm getting this same error upon starting my app under the profiler. Here's the error info & stack trace:
    8/21/2006 10:11:21 AM. An error of type System.BadImageFormatException occurred:
    
    Error message: Bad class token.
    
    Error stack trace: 
       at MyCompany.Collections.Algorithms.ConvertToArray[TReturn,TItem](IEnumerable`1 items, Converter`2 converter)
       at MyCompany.MyApp.Client.ServerCommunication.ClientDataReader.ReadUser(String name, String password) in C:\Documents and Settings\Judah Himango\My Documents\Visual Studio\Projects\Judah\MyCompany.MyApp.Client\ServerCommunication\ClientDataReader.cs:line 630
       at MyCompany.MyApp.Client.ServerCommunication.LoginManager.Login(String userName, String password) in C:\Documents and Settings\Judah Himango\My Documents\Visual Studio\Projects\Judah\MyCompany.MyApp.Client\ServerCommunication\RemoteLogin.cs:line 132
       at MyCompany.MyApp.Client.LoginForm.LoginUser(LoginArgs args) in C:\Documents and Settings\Judah Himango\My Documents\Visual Studio\Projects\Judah\MyCompany.MyApp.Client\ServerCommunication\LoginForm.cs:line 386
       at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
       at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(RuntimeMethodHandle md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
       at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
    

    As you can see, this happened in the Algorithms.ConvertToArray method. That method is a simple method that converts any generic IEnumerable to an array. Here's the code snippet for that method:
    public static TReturn[] ConvertToArray<TReturn, TItem>(IEnumerable<TItem> items, Converter<TItem, TReturn> converter)
    {
         TReturn[] retVal = new TReturn[Algorithms.Count<TItem>(items)];
         int i = 0;
         foreach (TItem item in items)
         {
              retVal[i++] = converter(item);
         }
    
         return retVal;
    }
    

    Algorithms.Count is a method that simply counts the number of items in a generic IEnumerable by doing a foreach over the elements, incrementing an integer each iteration.

    So this time the error happened when converting a generic IEnumerable to an array. It previously occurred (see the first post above) when converting a generic IList to an array. It seems the profiler is having a hard time on this.
  • I tried putting that code in a simple WinForms test project and ran that under the profiler. Unfortunately, it seems to work just fine. I can consistently repro the error every time in our main client app, but I cannot inside a test project, unfortunately.

    Judging by the pieces of code that cause the BadImageFormatException, this seems almost certainly due to copying a generic IEnumerable to an array.

    Also, in both places, the error was thrown while on a background thread. So it may have something to do with multiple threads running. Hard to say for sure.

    Again, the key seems to be copying a generic IEnumerable to an array: this time it happens in my custom code that copies an IEnumerable to an array, previously the error happened in the .NET framework's List<T>.CopyTo method.
  • Hi guys

    Version 2.7 fixes this problem. Thanks!
  • Brian DonahueBrian Donahue Posts: 6,590 New member
    Hi,

    I'm glad that we've sorted this out for you!
  • Update: after further profiling, it seems this bug is still occurring in v2.7.

    I've looked into where the BadImageFormatException is getting thrown, and I've found it's being thrown in the same place: in a call to the ConvertToArray method.

    If I delete the pdb files for my application prior to profiling, it works. Of course, no methods are then instrumented, so that's hardly a work-around.

    Since I cannot, at this time, send you the application causing the problem, and since I can't seem to get a reproducible test case going, is there some way you guys could give me a special build with some verbose logging to help track down the problem? I'd really like to solve this one. It'd be in the best interest of both myself and Red Gate to have this problem solved.
  • Guys, I've got a reproducible test case for you. See the end of this post for more info and for the repro case download.

    p.s. this bug is still occurring in 2.7.1 -- this has been plaguing us for months, so I'd love to have it fixed! Thanks.
  • Never mind that previous post, here's a link to a repro case that shows it: Bad Class Token.zip.

    When running the above project under the ants profiler, click the big button, and the error will be thrown.
  • 'System.BadImageFormatException' occurred and was caught.
    Bad class token :?

    I'm evalueting ants profiler right now, bud we can't profile our application.
    This exception is throw at startup
  • I am also having this problem. We recently purchased profiler. Our data abstraction layer is based on generics, so I hope the problem is resolved soon. The problem only showed up recently and is sporadic. We have run many profiles without problems until now.
  • Hi Stuart,

    Are you seeing this on version 2 or version 3 of ANTS Profiler? If you're on V2, I suggest upgrading, as this will probably fix it.

    Regards,
    Robert
    Robert Chipperfield
    Red Gate
Sign In or Register to comment.