From 82804300a7969f7f8f4e20c60153eac09ddb41b3 Mon Sep 17 00:00:00 2001 From: ElektroKill <elektrokilldev@protonmail.com> Date: Wed, 27 Sep 2023 21:31:27 +0200 Subject: [PATCH] Provide custom type info for return values in Mono debugger --- .../Evaluation/DbgMonoDebugInternalRuntimeImpl.cs | 15 +++++++++++++-- .../Evaluation/Engine/DbgEngineLanguageImpl.cs | 3 ++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.Mono/Impl/Evaluation/DbgMonoDebugInternalRuntimeImpl.cs b/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.Mono/Impl/Evaluation/DbgMonoDebugInternalRuntimeImpl.cs index ddfb8941d7..69b9e6e557 100644 --- a/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.Mono/Impl/Evaluation/DbgMonoDebugInternalRuntimeImpl.cs +++ b/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet.Mono/Impl/Evaluation/DbgMonoDebugInternalRuntimeImpl.cs @@ -27,6 +27,7 @@ You should have received a copy of the GNU General Public License using dnSpy.Contracts.Debugger.CallStack; using dnSpy.Contracts.Debugger.DotNet.Disassembly; using dnSpy.Contracts.Debugger.DotNet.Evaluation; +using dnSpy.Contracts.Debugger.DotNet.Evaluation.ExpressionCompiler; using dnSpy.Contracts.Debugger.DotNet.Mono; using dnSpy.Contracts.Debugger.Engine.Evaluation; using dnSpy.Contracts.Debugger.Evaluation; @@ -626,6 +627,7 @@ DbgDotNetAliasInfo[] GetAliasesCore(DbgEvaluationInfo evalInfo) { exception = GetExceptionCore(evalInfo, DbgDotNetRuntimeConstants.ExceptionId); stowedException = GetStowedExceptionCore(evalInfo, DbgDotNetRuntimeConstants.StowedExceptionId); returnValues = GetReturnValuesCore(evalInfo); + evalInfo.Context.TryGetData(out DbgDotNetExpressionCompiler? expressionCompiler); int count = (exception is not null ? 1 : 0) + (stowedException is not null ? 1 : 0) + returnValues.Length + (returnValues.Length != 0 ? 1 : 0); if (count == 0) @@ -638,10 +640,19 @@ DbgDotNetAliasInfo[] GetAliasesCore(DbgEvaluationInfo evalInfo) { if (stowedException is not null) res[w++] = new DbgDotNetAliasInfo(DbgDotNetAliasInfoKind.StowedException, stowedException.Type, DbgDotNetRuntimeConstants.StowedExceptionId, null); if (returnValues.Length != 0) { - res[w++] = new DbgDotNetAliasInfo(DbgDotNetAliasInfoKind.ReturnValue, returnValues[returnValues.Length - 1].Value.Type, DbgDotNetRuntimeConstants.LastReturnValueId, null); + var lastReturnVal = returnValues[returnValues.Length - 1]; + res[w++] = new DbgDotNetAliasInfo(DbgDotNetAliasInfoKind.ReturnValue, lastReturnVal.Value.Type, DbgDotNetRuntimeConstants.LastReturnValueId, CreateCustomTypeInfo(lastReturnVal)); + foreach (var returnValue in returnValues) { Debug.Assert(returnValue.Id != DbgDotNetRuntimeConstants.LastReturnValueId); - res[w++] = new DbgDotNetAliasInfo(DbgDotNetAliasInfoKind.ReturnValue, returnValue.Value.Type, returnValue.Id, null); + res[w++] = new DbgDotNetAliasInfo(DbgDotNetAliasInfoKind.ReturnValue, returnValue.Value.Type, returnValue.Id, CreateCustomTypeInfo(returnValue)); + } + + DbgDotNetCustomTypeInfo? CreateCustomTypeInfo(DbgDotNetReturnValueInfo returnVal) { + var method = returnVal.Method as DmdMethodInfo; + if (method?.ReturnType.Equals(returnVal.Value.Type) == true) + return expressionCompiler?.CreateCustomTypeInfo(method.ReturnParameter); + return null; } } if (w != res.Length) diff --git a/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet/Evaluation/Engine/DbgEngineLanguageImpl.cs b/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet/Evaluation/Engine/DbgEngineLanguageImpl.cs index 779ca65563..c01f509759 100644 --- a/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet/Evaluation/Engine/DbgEngineLanguageImpl.cs +++ b/Extensions/dnSpy.Debugger/dnSpy.Debugger.DotNet/Evaluation/Engine/DbgEngineLanguageImpl.cs @@ -123,7 +123,8 @@ public override void InitializeContext(DbgEvaluationContext context, DbgCodeLoca Debug2.Assert(context.Runtime.GetDotNetRuntime() is not null); IDebuggerDisplayAttributeEvaluatorUtils.Initialize(context, debuggerDisplayAttributeEvaluator); - // Needed by DebuggerRuntimeImpl (calls expressionCompiler.TryGetAliasInfo()), DbgCorDebugInternalRuntimeImpl and DbgEngineStaticFieldsProviderImpl (calls expressionCompiler.CreateCustomTypeInfo()) + // Needed by DebuggerRuntimeImpl (calls expressionCompiler.TryGetAliasInfo()), DbgCorDebugInternalRuntimeImpl, + // DbgMonoDebugInternalRuntimeImpl and DbgEngineStaticFieldsProviderImpl (calls expressionCompiler.CreateCustomTypeInfo()) context.GetOrCreateData(() => expressionCompiler); if ((context.Options & DbgEvaluationContextOptions.NoMethodBody) == 0 && location is IDbgDotNetCodeLocation loc) {