[.NET] TypeDefinition.Fields (and possibly other member getters) isn't thread-safe
Closed this issue · 3 comments
SamboyCoding commented
Describe the bug
As discussed in discord, calling
moduleDef.GetAllTypes().AsParallel().SelectMany(t => t.Fields).Count();
Throws the following exception
System.BadImageFormatException: Field 0400016E is not in the range of a declaring type.
at AsmResolver.ThrowErrorListener.RegisterException(Exception exception)
at AsmResolver.DotNet.Serialized.SerializedFieldDefinition.GetDeclaringType()
at AsmResolver.LazyVariable`1.InitializeValue()
at AsmResolver.DotNet.FieldDefinition.AsmResolver.Collections.IOwnedCollectionElement<AsmResolver.DotNet.TypeDefinition>.get_Owner()
at AsmResolver.Collections.OwnedCollection`2.AssertNotNullAndHasNoOwner(TItem item)
at AsmResolver.Collections.OwnedCollection`2.OnInsertItem(Int32 index, TItem item)
at AsmResolver.DotNet.Serialized.SerializedTypeDefinition.CreateMemberCollection[TMember](MetadataRange range)
at AsmResolver.DotNet.Serialized.SerializedTypeDefinition.GetFields()
at AsmResolver.DotNet.TypeDefinition.get_Fields()
at System.Linq.Parallel.SelectManyQueryOperator`3.SelectManyQueryOperatorEnumerator`1.MoveNext(TOutput& currentElement, Pair`2& currentKey)
While calling the same thing without the AsParallel()
works as expected.
To Reproduce
Load a module, and call moduleDef.GetAllTypes().AsParallel().SelectMany(t => t.Fields).Count()
. As this is a thread-safety issue, it's possible you may have to call it multiple times to reproduce the issue.
Expected behavior
The total number of field definitions in the module is returned, but (hopefully) faster than doing so single-threaded.
Screenshots
N/A
Platform
- OS: Windows 11
- AsmResolver Version: 4.9.0
Additional context
N/A
Washi1337 commented
Potential fix has been pushed in #300. Could you verify this indeed solves the issue?
SamboyCoding commented
Yep, that seems to fix the issue.
Washi1337 commented
Perfect. Thanks for spotting.