locked
IndexOutOfRangeException in ConditionalWeakTable.GetOrCreateValue() RRS feed

  • Question

  •    

    I am using ConditionalWeakTable as part of a weak event handler implementation. It works fine, except occasionally I get automatic crash logs from my users indicating that a call to GetOrCreateValue() has crashed.

    The error and call stack looks like one of the following two stacks, I assume depending on whether there's an existing entry or a new one needs to get created:

    System.IndexOutOfRangeException: Index was outside the bounds of the array.
       at System.Runtime.CompilerServices.ConditionalWeakTable`2.CreateEntry(TKey key, TValue value)
       at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValue(TKey key, CreateValueCallback createValueCallback)
       at [my code]
    System.IndexOutOfRangeException: Index was outside the bounds of the array.
       at System.Runtime.CompilerServices.ConditionalWeakTable`2.FindEntry(TKey key)
       at System.Runtime.CompilerServices.ConditionalWeakTable`2.TryGetValueWorker(TKey key, TValue& value)
       at System.Runtime.CompilerServices.ConditionalWeakTable`2.TryGetValue(TKey key, TValue& value)
       at System.Runtime.CompilerServices.ConditionalWeakTable`2.GetValue(TKey key, CreateValueCallback createValueCallback)
       at [my code]

    (The actual call to GetOrCreateValue() appears to have been inlined.)

    Here's my code that declares the ConditionalWeakTable:

    private static readonly ConditionalWeakTable<object, Dictionary<EventInfo, object>> s_sourceObjects = new ConditionalWeakTable<object, Dictionary<EventInfo, object>>();

    Here's my code that calls GetOrCreateValue():

    Dictionary<EventInfo, object> events;
    lock(s_sourceObjects)
        events = s_sourceObjects.GetOrCreateValue(sourceObject);

    And here's the only other place that references the s_sourceObjects field:

    bool success;
    Dictionary<EventInfo, object> events;
    lock(s_sourceObjects)
        success = s_sourceObjects.TryGetValue(sourceObject, out events);

    (I added the lock statements because I suspected there was a thread-safety bug in ConditionalWeakTable despite the documentation claiming it's thread-safe. However, the bug still occurs even with the lock statements, so apparently it's not a threading issue.)

    My application uses .NET 4.6.2.

    Am I somehow misusing or not understanding ConditionalWeakTable? Or is this a framework bug? If it's a framework bug, is there any way I can work around it?

    Here's the entire source code for the class, if anyone wants to see the context: https://gist.github.com/waltdestler/2a339bdd0d7d647501eb4690772e3b50

    Thanks for your help!

    Tuesday, August 1, 2017 9:06 PM

All replies

  • Hi Walt Destler,

    The IndexOutOfRangeException means that you're trying to access a collection item by index, using an invalid index. An index is invalid when it's lower than the collection's lower bound or greater than or equal to the number of elements it contains.

    I check the code you provided, I do not find the place which could cause the exception.

    Could you debug your code and provide where you get the exception?

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, August 2, 2017 10:08 AM
  • I looked in ConditionalWeakTable but didn't find such a bug (except one in a comment). I presume Microsoft has unit tests for that class, anyway.

    Those methods access two arrays: _buckets and _entries. Can you get a memory dump and find out which array threw the exception and what the index was? Even better, list the entire contents of the arrays and check what out-of-range value caused the exception and whether any other values are also out of range.

    Are you getting multiple crash reports from the same computer, or are they randomly distributed?

    The error could be caused by memory corruption, due to invalid pointers in unsafe code or hardware failure. I expect that would often corrupt a reference instead, and the CLR would soon crash the process with an uncatchable exception. Have you registered to get statistics about those crashes from Microsoft?

    Saturday, August 5, 2017 6:30 AM
  • Hi Walt Destler,

    Have you solved your problem?

    If you solved your problem, please mark the useful reply as answer. This will make answer searching in the forum and be beneficial to community members as well.

    If you have something else about this issue, please feel free to contact us.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Sunday, August 27, 2017 2:12 PM