Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.NullReferenceException: at ICSharpCode.Decompiler.CSharp.TranslatedExpression.ConvertTo() #2092

Closed
greenozon opened this issue Aug 4, 2020 · 2 comments
Labels
Bug Decompiler The decompiler engine itself

Comments

@greenozon
Copy link

Input code

Save code

see the error:

Erroneous output

Error decompiling @06001820 NuGet.ProjectManager.RemovePackageReferenceFromProject
in assembly "C:\app-0.0.306\Squirrel.exe"
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at ICSharpCode.Decompiler.CSharp.TranslatedExpression.ConvertTo(IType targetType, ExpressionBuilder expressionBuilder, Boolean checkForOverflow, Boolean allowImplicitConversion) in offset 331
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitLeave(Leave inst) in offset 97
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in offset 14
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockStatement blockStatement, BlockContainer container, IEnumerable`1 blocks, Boolean isLoop) in offset 0
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockContainer container, Boolean isLoop) in offset 6
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitBlockContainer(BlockContainer container) in offset 160
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in offset 14
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertAsBlock(ILInstruction inst) in offset 0
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.TranslateFunction(IType delegateType, ILFunction function) in offset 155
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.VisitILFunction(ILFunction function, TranslationContext context) in offset 0
   at ICSharpCode.Decompiler.IL.ILFunction.AcceptVisitor[C,T](ILVisitor`2 visitor, C context) in offset 0
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.Translate(ILInstruction inst, IType typeHint) in offset 41
   at ICSharpCode.Decompiler.CSharp.CallBuilder.BuildArgumentList(ExpectedTargetDetails expectedTargetDetails, ResolveResult target, IMethod method, Int32 firstParamIndex, IReadOnlyList`1 callArguments, IReadOnlyList`1 argumentToParameterMap) in offset 199
   at ICSharpCode.Decompiler.CSharp.CallBuilder.Build(OpCode callOpCode, IMethod method, IReadOnlyList`1 callArguments, IReadOnlyList`1 argumentToParameterMap, IType constrainedTo) in offset 418
   at ICSharpCode.Decompiler.CSharp.CallBuilder.Build(CallInstruction inst) in offset 308
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.VisitCall(Call inst, TranslationContext context) in offset 19
   at ICSharpCode.Decompiler.IL.Call.AcceptVisitor[C,T](ILVisitor`2 visitor, C context) in offset 0
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.Translate(ILInstruction inst, IType typeHint) in offset 41
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.VisitStLoc(StLoc inst, TranslationContext context) in offset 0
   at ICSharpCode.Decompiler.IL.StLoc.AcceptVisitor[C,T](ILVisitor`2 visitor, C context) in offset 0
   at ICSharpCode.Decompiler.CSharp.ExpressionBuilder.Translate(ILInstruction inst, IType typeHint) in offset 41
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitStLoc(StLoc inst) in offset 0
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in offset 14
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockStatement blockStatement, BlockContainer container, IEnumerable`1 blocks, Boolean isLoop) in offset 0
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertBlockContainer(BlockContainer container, Boolean isLoop) in offset 6
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.VisitBlockContainer(BlockContainer container) in offset 160
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.Convert(ILInstruction inst) in offset 14
   at ICSharpCode.Decompiler.CSharp.StatementBuilder.ConvertAsBlock(ILInstruction inst) in offset 0
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in offset 617
-- continuing with outer exception (ICSharpCode.Decompiler.DecompilerException) --
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in offset 832
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.DoDecompile(IMethod method, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in offset 195
   at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.Decompile(IEnumerable`1 definitions) in offset 370
   at ICSharpCode.ILSpy.CSharpLanguage.DecompileMethod(IMethod method, ITextOutput output, DecompilationOptions options) in offset 247
   at ICSharpCode.ILSpy.TextView.DecompilerTextView.DecompileNodes(DecompilationContext context, ITextOutput textOutput) in offset 124
   at ICSharpCode.ILSpy.TextView.DecompilerTextView.<>c__DisplayClass48_0.<DecompileAsync>b__0() in offset 36


Details

  • Product in use: ILSpy 6.1 release

Squirrel.zip

@greenozon greenozon added Bug Decompiler The decompiler engine itself labels Aug 4, 2020
@dgrunwald
Copy link
Member

The problem is an expression tree that has ReturnType == null.

@dgrunwald
Copy link
Member

Root cause seems to be that this assembly has two mscorlib references, both to version 2.0 and 4.0. It looks like ilmerge was used to combine multiple assemblies with different target frameworks.
This confuses our type system, resulting in an UnknownType for System.Func.

This in turn means we can't find the Invoke method and thus lack a return type. Apparently the expression tree transform then uses null instead of the usual SpecialType.UnknownType. This later causes a crash as we assume return types to never null.
I've fixed the crash by adding a fallback to SpecialType.UnknownType on this code path; but the decompilation result is still extremely poor due to the type system issues.

dgrunwald added a commit that referenced this issue Aug 6, 2020
…type system.

We now avoid the old `IModuleReference` interface which required allocating for every type being resolved.
Instead `MetadataModule.ResolveModule` now combines decoding+resolving assembly references into a single step.
This allows the type system to maintain a cache indexed by row number.

This also changes the behavior of resolving references within a compilation: We now prefer an exact match (name + version + publickeytoken) first; and fall back to a name-only match only if no exact match exists.
This somewhat improves the decompilation of assemblies created by using ilmerge to combine assemblies with different target frameworks.
siegfriedpammer added a commit that referenced this issue Jun 18, 2021
…formExpressionTrees.MatchGetContructorFromHandle use IType.FullName instead of actual IType instances, so we can better handle assemblies processed by tools like ILMerge, where there might be used multiple versions of mscorlib in one assembly.
ElektroKill added a commit to dnSpyEx/ILSpy that referenced this issue Aug 8, 2021
ElektroKill pushed a commit to dnSpyEx/ILSpy that referenced this issue Aug 11, 2021
…e and TransformExpressionTrees.MatchGetContructorFromHandle use IType.FullName instead of actual IType instances, so we can better handle assemblies processed by tools like ILMerge, where there might be used multiple versions of mscorlib in one assembly.
ElektroKill added a commit to dnSpyEx/ILSpy that referenced this issue Aug 11, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Decompiler The decompiler engine itself
Projects
None yet
Development

No branches or pull requests

2 participants