diff --git a/LuaDebugAttacher_x64/LuaDebugAttacher_x64.vcxproj b/LuaDebugAttacher_x64/LuaDebugAttacher_x64.vcxproj index c38ab2d..44331e6 100644 --- a/LuaDebugAttacher_x64/LuaDebugAttacher_x64.vcxproj +++ b/LuaDebugAttacher_x64/LuaDebugAttacher_x64.vcxproj @@ -14,19 +14,19 @@ 16.0 {4D877B09-CA72-4416-B2F9-B4E243C0D51F} LuaDebugAttacherx64 - 10.0.17763.0 + 10.0 Application true - v141 + v143 Unicode Application false - v141 + v143 true Unicode diff --git a/LuaDebugHelper_x64/LuaDebugHelper_x64.vcxproj b/LuaDebugHelper_x64/LuaDebugHelper_x64.vcxproj index f5a74ba..764594b 100644 --- a/LuaDebugHelper_x64/LuaDebugHelper_x64.vcxproj +++ b/LuaDebugHelper_x64/LuaDebugHelper_x64.vcxproj @@ -15,19 +15,19 @@ {D0A573AC-3559-4D68-B617-0EEC056FA018} Win32Proj LuaDebugHelperx64 - 10.0.17763.0 + 10.0 DynamicLibrary true - v141 + v143 Unicode DynamicLibrary false - v141 + v143 false Unicode diff --git a/LuaDebugHelper_x86/LuaDebugHelper_x86.vcxproj b/LuaDebugHelper_x86/LuaDebugHelper_x86.vcxproj index e23d2ca..292a6cb 100644 --- a/LuaDebugHelper_x86/LuaDebugHelper_x86.vcxproj +++ b/LuaDebugHelper_x86/LuaDebugHelper_x86.vcxproj @@ -15,19 +15,19 @@ {043C0981-A01F-46F4-A19C-FDCD72973492} Win32Proj LuaDebugHelperx86 - 10.0.17763.0 + 10.0 DynamicLibrary true - v141 + v143 Unicode DynamicLibrary false - v141 + v143 false Unicode diff --git a/LuaDkmDebugger17/Properties/AssemblyInfo.cs b/LuaDkmDebugger17/Properties/AssemblyInfo.cs index 2cbe719..cdc4ffc 100644 --- a/LuaDkmDebugger17/Properties/AssemblyInfo.cs +++ b/LuaDkmDebugger17/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.0.0.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/LuaDkmDebuggerCommon/LuaDkmDebuggerPackage.cs b/LuaDkmDebuggerCommon/LuaDkmDebuggerPackage.cs index 09ef225..99616a8 100644 --- a/LuaDkmDebuggerCommon/LuaDkmDebuggerPackage.cs +++ b/LuaDkmDebuggerCommon/LuaDkmDebuggerPackage.cs @@ -61,6 +61,7 @@ public sealed class LuaDkmDebuggerPackage : AsyncPackage public const int LuaInitializeCommandId = 0x0170; public const int LuaShowScriptListCommandId = 0x0180; public const int LuaEvalFuncOnHoverCommandId = 0x0190; + public const int LuaShowInternalMethodsCommandId = 0x0200; public static readonly Guid CommandSet = new Guid("6EB675D6-C146-4843-990E-32D43B56706C"); @@ -75,6 +76,7 @@ public sealed class LuaDkmDebuggerPackage : AsyncPackage public static bool releaseDebugLogs = false; public static bool showHiddenFrames = false; public static bool useSchema = false; + public static bool showInternalMethods = false; private WritableSettingsStore configurationSettingsStore = null; @@ -107,6 +109,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke releaseDebugLogs = configurationSettingsStore.GetBoolean("LuaDkmDebugger", "ReleaseDebugLogs", false); showHiddenFrames = configurationSettingsStore.GetBoolean("LuaDkmDebugger", "ShowHiddenFrames", false); useSchema = configurationSettingsStore.GetBoolean("LuaDkmDebugger", "UseSchema", false); + showInternalMethods = configurationSettingsStore.GetBoolean("LuaDkmDebugger", "ShowInternalMethods", false); LuaDkmDebuggerComponent.LocalComponent.attachOnLaunch = attachOnLaunch; LuaDkmDebuggerComponent.LocalComponent.breakOnError = breakOnError; @@ -281,6 +284,26 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke commandService.AddCommand(menuItem); } + + { + CommandID menuCommandID = new CommandID(CommandSet, LuaShowInternalMethodsCommandId); + + OleMenuCommand menuItem = new OleMenuCommand((object sender, EventArgs args) => + { + HandleToggleMenuItem(sender, args, "ShowInternalMethods", ref LuaDkmDebuggerComponent.LocalComponent.showInternalMethods, ref showInternalMethods); + }, menuCommandID); + + menuItem.BeforeQueryStatus += (object sender, EventArgs args) => + { + if (sender is OleMenuCommand command) + command.Checked = showInternalMethods; + }; + + menuItem.Enabled = true; + menuItem.Checked = showInternalMethods; + + commandService.AddCommand(menuItem); + } } try diff --git a/LuaDkmDebuggerComponent/EvaluationHelpers.cs b/LuaDkmDebuggerComponent/EvaluationHelpers.cs index fe1b0e1..86f5a53 100644 --- a/LuaDkmDebuggerComponent/EvaluationHelpers.cs +++ b/LuaDkmDebuggerComponent/EvaluationHelpers.cs @@ -6,11 +6,51 @@ using System; using System.Collections.ObjectModel; using System.Diagnostics; +using System.Xml.Linq; namespace LuaDkmDebuggerComponent { internal class EvaluationHelpers { + public static bool IsInternalMember(string name) + { + if (name == "__index" + || (name == "__newindex") + || (name == "__mode") + || (name == "__call") + || (name == "__metatable") + || (name == "__tostring") + || (name == "__len") + || (name == "__name") + || (name == "__close") + || (name == "__gc") + //Mathematic Operators + || (name == "__unm") + || (name == "__add") + || (name == "__sub") + || (name == "__mul") + || (name == "__div") + || (name == "__idiv") + || (name == "__mod") + || (name == "__pow") + || (name == "__concat") + || (name == "__mod") + //Bitwise Operators + || (name == "__band") + || (name == "__bor") + || (name == "__bxor") + || (name == "__bnot") + || (name == "__shl") + || (name == "__shr") + //Equivalence Comparison Operators + || (name == "__eq") + || (name == "__lt") + || (name == "__le")) + return true; + + return false; + } + internal static DkmEvaluationResult ExecuteRawExpression(string expression, DkmInspectionSession inspectionSession, DkmThread thread, DkmStackWalkFrame input, DkmRuntimeInstance runtimeInstance, DkmEvaluationFlags flags) { var compilerId = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp); @@ -280,10 +320,13 @@ internal static string EvaluateValueAtLuaValue(DkmProcess process, LuaValueDataB { var value = valueBase as LuaValueDataUserData; - type = "user_data"; + string luabindClassName = null; + string toStringResult = null; + + type = luabindClassName?.Length > 0 ? $"luabind class {luabindClassName} (user_data)" : "user_data"; flags |= DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable; - return $"0x{value.targetAddress:x}"; + return toStringResult?.Length > 0 ? $"{toStringResult} (0x{value.targetAddress:x})" : $"0x{value.targetAddress:x}"; } if (valueBase as LuaValueDataThread != null) @@ -461,10 +504,15 @@ internal static DkmEvaluationResult GetTableChildAtIndex(DkmInspectionContext in isIdentifierName = pos == name.Length; } + var accessFlag = DkmEvaluationResultAccessType.None; + + if (IsInternalMember(name)) + accessFlag |= DkmEvaluationResultAccessType.Internal; + if (isIdentifierName) - return EvaluateDataAtLuaValue(inspectionContext, stackFrame, name, $"{fullName}.{name}", node.LoadValue(process, value.batchNodeElementData), DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None); + return EvaluateDataAtLuaValue(inspectionContext, stackFrame, name, $"{fullName}.{name}", node.LoadValue(process, value.batchNodeElementData), DkmEvaluationResultFlags.None, accessFlag, DkmEvaluationResultStorageType.None); - return EvaluateDataAtLuaValue(inspectionContext, stackFrame, $"\"{name}\"", $"{fullName}[\"{name}\"]", node.LoadValue(process, value.batchNodeElementData), DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None); + return EvaluateDataAtLuaValue(inspectionContext, stackFrame, $"\"{name}\"", $"{fullName}[\"{name}\"]", node.LoadValue(process, value.batchNodeElementData), DkmEvaluationResultFlags.None, accessFlag, DkmEvaluationResultStorageType.None); } index = index - nodeElementCount; diff --git a/LuaDkmDebuggerComponent/ExpressionEvaluation.cs b/LuaDkmDebuggerComponent/ExpressionEvaluation.cs index 9f9febe..d049fe0 100644 --- a/LuaDkmDebuggerComponent/ExpressionEvaluation.cs +++ b/LuaDkmDebuggerComponent/ExpressionEvaluation.cs @@ -1,6 +1,7 @@ using Microsoft.VisualStudio.Debugger; using Microsoft.VisualStudio.Debugger.CallStack; using Microsoft.VisualStudio.Debugger.Evaluation; +using System.Collections.Generic; namespace LuaDkmDebuggerComponent { @@ -201,8 +202,8 @@ public LuaValueDataBase LookupTableMember(LuaValueDataTable tableValue, LuaTable return result; } - return Report($"Failed to find key '{name}' in table"); - } + return Report($"Failed to find key '{name}' in table"); + } public LuaValueDataBase LookupTableElement(LuaValueDataTable table, LuaValueDataBase index) { @@ -513,9 +514,73 @@ public string TryParseIdentifier() return null; } + public LuaValueDataBase EvaluateCallExpressions(LuaValueDataBase value, LuaValueDataBase parentValue = null) + { + var currentValue = value; + if (TryTakeToken("(")) + { + var argsStart = pos; + if (expression.LastIndexOf(")") == -1) + return Report("Failed to find ')' after '('"); + + if (process == null) + return Report("Can't load table - process memory is not available"); + + if (value is LuaValueDataTable indexMetaTableValueTable) //Usefull?? + { + value = LookupTableMember(indexMetaTableValueTable, indexMetaTableValueTable.value, "__call"); + } + else + { + LuaValueDataBase[] arguments = null; + if (argsStart + 1 != pos) // not a simple call like foo() + { + var savePos = pos = expression.LastIndexOf(")"); + var saveExpression = expression; + + var argsStr = expression.Substring(argsStart, pos - argsStart); + var argsArray = argsStr.Split(new char[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries); + arguments = new LuaValueDataBase[argsArray.Length]; + for (int i = 0; i < argsArray.Length; i++) + { + arguments[i] = Evaluate(argsArray[i], allowSideEffects); + } + + pos = savePos + 1; + expression = saveExpression; + } - public LuaValueDataBase EvaluatePostExpressions(LuaValueDataBase value) + List callArgs = new List { value }; // function, (this), function args + + if (parentValue != null) + callArgs.Add(parentValue); + + if (arguments != null) + callArgs.AddRange(arguments); + + if (value is LuaValueDataLuaFunction) + { + value = EvaluateCall(callArgs.ToArray()); + } + else if (value is LuaValueDataExternalClosure) + { + value = EvaluateCall(callArgs.ToArray()); + } + else + return Report("Failed to evaluate call"); + } + + if (value as LuaValueDataError != null) + return value; + + return EvaluatePostExpressions(value, currentValue); + } + + return value; + } + public LuaValueDataBase EvaluatePostExpressions(LuaValueDataBase value, LuaValueDataBase parentValue = null) { + var currentValue = value; if (TryTakeToken(".") || TryTakeToken(":")) { string name = TryParseIdentifier(); @@ -557,7 +622,7 @@ public LuaValueDataBase EvaluatePostExpressions(LuaValueDataBase value) if (value as LuaValueDataError != null) return value; - return EvaluatePostExpressions(value); + return EvaluatePostExpressions(value, parentValue); } if (TryTakeToken("[")) @@ -583,10 +648,10 @@ public LuaValueDataBase EvaluatePostExpressions(LuaValueDataBase value) if (value as LuaValueDataError != null) return value; - return EvaluatePostExpressions(value); + return EvaluatePostExpressions(value, currentValue); } - return value; + return EvaluateCallExpressions(value, parentValue); } // group variable @@ -1066,8 +1131,8 @@ public LuaValueDataBase Evaluate(string expression, bool allowSideEffects) SkipSpace(); - if (pos < expression.Length) - return Report(value, $"Failed to fully parse at '{expression.Substring(pos)}'"); + if (this.pos < this.expression.Length) + return Report(value, $"Failed to fully parse at '{this.expression.Substring(this.pos)}'"); return value; } diff --git a/LuaDkmDebuggerComponent/LocalComponent.cs b/LuaDkmDebuggerComponent/LocalComponent.cs index f158e37..3191326 100644 --- a/LuaDkmDebuggerComponent/LocalComponent.cs +++ b/LuaDkmDebuggerComponent/LocalComponent.cs @@ -12,11 +12,13 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Linq.Expressions; using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Web.Script.Serialization; +using System.Xml.Linq; namespace LuaDkmDebuggerComponent { @@ -234,13 +236,12 @@ public class LocalComponent : IDkmCallStackFilter, IDkmSymbolQuery, IDkmSymbolCo public static bool releaseDebugLogs = false; public static bool showHiddenFrames = false; public static bool useSchema = false; - + public static bool showInternalMethods = false; #if DEBUG public static Log log = new Log(Log.LogLevel.Debug, true); #else public static Log log = new Log(Log.LogLevel.Error, true); #endif - internal void LoadConfigurationFile(DkmProcess process, LuaLocalProcessData processData) { // Check if already loaded @@ -1878,13 +1879,63 @@ void IDkmLanguageExpressionEvaluator.GetChildren(DkmEvaluationResult result, Dkm if (parentFrameData != null) nativeTypeName = value.value.GetNativeType(process); - int actualSize = value.value.metaTable.GetArrayElementCount(process) + value.value.metaTable.GetNodeElementCount(process) + (nativeTypeName != null ? 1 : 0); + //Luabind Ext + List finalResults = new List(); + int luabindExtMembersCount = 0; + { + // Load frame data from instruction + var instructionAddress = result.StackFrame.InstructionAddress as DkmCustomInstructionAddress; - int finalInitialSize = initialRequestSize < actualSize ? initialRequestSize : actualSize; + Debug.Assert(instructionAddress != null); + var frameData = new LuaFrameData(); - DkmEvaluationResult[] initialResults = new DkmEvaluationResult[finalInitialSize]; + if (!frameData.ReadFrom(instructionAddress.AdditionalData.ToArray())) + { + log.Error($"IDkmLanguageExpressionEvaluator.EvaluateExpression failure (no frame data)"); - for (int i = 0; i < initialResults.Length; i++) + completionRoutine(new DkmGetChildrenAsyncResult(new DkmEvaluationResult[0], DkmEvaluationResultEnumContext.Create(0, result.StackFrame, inspectionContext, null))); + return; + } + GetEvaluationSessionData(process, inspectionContext.InspectionSession, frameData, out LuaFunctionCallInfoData callInfoData, out LuaFunctionData functionData, out LuaClosureData closureData); + ExpressionEvaluation evaluation = new ExpressionEvaluation(process, result.StackFrame, inspectionContext.InspectionSession, functionData, callInfoData.stackBaseAddress, closureData); + + var expr = $"class_info({result.FullName}).attributes"; + var luabindClassAttributes = evaluation.Evaluate(expr, true) as LuaValueDataTable; + if(luabindClassAttributes != null) + { + luabindExtMembersCount = (int)(luabindClassAttributes?.value?.arraySize); + + if (luabindExtMembersCount > 0) + { + var attGetters = luabindClassAttributes.value.GetArrayElements(process); + foreach (LuaValueDataBase getter in attGetters) + { + if (getter is LuaValueDataString luaName) + { + var attribValue = evaluation.Evaluate($"{result.FullName}.{luaName.value}({result.FullName})", true); + + luabindClassAttributes.value.GetNodeElements(process); + var dkmResult = EvaluationHelpers.EvaluateDataAtLuaValue(inspectionContext, result.StackFrame, luaName.value, $"{result.FullName}.{luaName.value}", attribValue, DkmEvaluationResultFlags.None, DkmEvaluationResultAccessType.None, DkmEvaluationResultStorageType.None); + finalResults.Add(dkmResult); + } + } + } + } + } + var totalResultsCount = finalResults.Count; + + var currentRequestSize = initialRequestSize - finalResults.Count; + if(currentRequestSize < 0 ) + { + var removeCount = finalResults.Count - initialRequestSize; + finalResults.RemoveRange(finalResults.Count - removeCount - 1, removeCount); + currentRequestSize = 0; + } + int actualSize = value.value.metaTable.GetArrayElementCount(process) + value.value.metaTable.GetNodeElementCount(process) + (nativeTypeName != null ? 1 : 0); + int finalInitialSize = currentRequestSize < actualSize ? currentRequestSize : actualSize; + + totalResultsCount += actualSize; + for (int i = 0; i < finalInitialSize; i++) { int index = i; @@ -1892,19 +1943,19 @@ void IDkmLanguageExpressionEvaluator.GetChildren(DkmEvaluationResult result, Dkm { if (index == 0) { - initialResults[i] = GetNativeTypePseudoMember(inspectionContext, result.StackFrame, nativeTypeName, value.value.pointerAtValueStart); + finalResults.Add(GetNativeTypePseudoMember(inspectionContext, result.StackFrame, nativeTypeName, value.value.pointerAtValueStart)); continue; } index -= 1; } - initialResults[i] = EvaluationHelpers.GetTableChildAtIndex(inspectionContext, result.StackFrame, result.FullName, value.value.metaTable, index); + finalResults.Add(EvaluationHelpers.GetTableChildAtIndex(inspectionContext, result.StackFrame, result.FullName, value.value.metaTable, index)); } - var enumerator = DkmEvaluationResultEnumContext.Create(actualSize, result.StackFrame, inspectionContext, evalData); + var enumerator = DkmEvaluationResultEnumContext.Create(totalResultsCount, result.StackFrame, inspectionContext, evalData); - completionRoutine(new DkmGetChildrenAsyncResult(initialResults, enumerator)); + completionRoutine(new DkmGetChildrenAsyncResult(finalResults.ToArray(), enumerator)); log.Debug($"IDkmLanguageExpressionEvaluator.GetChildren success (table)"); return; @@ -2561,7 +2612,7 @@ DkmResolvedDocument[] IDkmSymbolDocumentCollectionQuery.FindDocuments(DkmModule var fileName = source.Value.resolvedFileName; - if (sourceFileId.DocumentName == fileName) + if (string.Compare(sourceFileId.DocumentName, fileName, true) == 0) { var dataItem = new LuaResolvedDocumentItem { @@ -2610,7 +2661,7 @@ DkmResolvedDocument[] IDkmSymbolDocumentCollectionQuery.FindDocuments(DkmModule var fileName = script.Value.resolvedFileName; - if (sourceFileId.DocumentName == fileName) + if (string.Compare(sourceFileId.DocumentName, fileName, true) == 0) { var dataItem = new LuaResolvedDocumentItem { diff --git a/LuaDkmDebuggerShared/LuaDkmDebugger.vsct b/LuaDkmDebuggerShared/LuaDkmDebugger.vsct index 4d4f4f4..073b65e 100644 --- a/LuaDkmDebuggerShared/LuaDkmDebugger.vsct +++ b/LuaDkmDebuggerShared/LuaDkmDebugger.vsct @@ -96,6 +96,16 @@ LuaShowScriptListCommandId + + @@ -113,6 +123,7 @@ + \ No newline at end of file diff --git a/MigrationBackup/1bc996cb/Tests/Tests.csproj b/MigrationBackup/1bc996cb/Tests/Tests.csproj new file mode 100644 index 0000000..2c99f75 --- /dev/null +++ b/MigrationBackup/1bc996cb/Tests/Tests.csproj @@ -0,0 +1,84 @@ + + + + + + Debug + AnyCPU + {78515BB1-C701-4ED0-AD5A-954106A97345} + Library + Properties + Tests + Tests + v4.7.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Microsoft.VisualStudio.Debugger.Interop.11.0.17.3.32804.24\lib\net472\Microsoft.VisualStudio.Debugger.Interop.11.0.dll + + + ..\packages\Microsoft.VisualStudio.Debugger.InteropA.17.3.32804.24\lib\net472\Microsoft.VisualStudio.Debugger.InteropA.dll + + + ..\packages\Microsoft.VisualStudio.Interop.17.3.32804.24\lib\net472\Microsoft.VisualStudio.Interop.dll + + + ..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + {671c8b4f-93f5-4aec-82e6-6c65a80798e7} + LuaDkmDebuggerComponent + + + + + + + Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. + + + + + + \ No newline at end of file diff --git a/MigrationBackup/1bc996cb/Tests/packages.config b/MigrationBackup/1bc996cb/Tests/packages.config new file mode 100644 index 0000000..c3128b5 --- /dev/null +++ b/MigrationBackup/1bc996cb/Tests/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index eb16835..b770266 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,6 +1,5 @@  - Debug @@ -39,13 +38,7 @@ 4 - - - ..\packages\MSTest.TestFramework.2.1.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.2.1.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - + @@ -53,23 +46,26 @@ - - - {671c8b4f-93f5-4aec-82e6-6c65a80798e7} LuaDkmDebuggerComponent + + + 17.0.2012801 + + + 17.3.32804.24 + + + 2.2.10 + + + 2.2.10 + + - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Tests/packages.config b/Tests/packages.config deleted file mode 100644 index 0d63e3f..0000000 --- a/Tests/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file