From: Oleg Lekarev Date: Wed, 13 Oct 2021 10:29:59 +0000 (+0300) Subject: sizeof() operator added to evaluator X-Git-Tag: submit/tizen/20220215.173642~30 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1ccee0f67d479f74c2a7aa204a333bbd57c466a8;p=sdk%2Ftools%2Fnetcoredbg.git sizeof() operator added to evaluator --- diff --git a/src/debugger/evalstackmachine.cpp b/src/debugger/evalstackmachine.cpp index 10123f9..4efa27a 100644 --- a/src/debugger/evalstackmachine.cpp +++ b/src/debugger/evalstackmachine.cpp @@ -133,6 +133,9 @@ namespace IfFailRet(pThread->CreateEval(&iCorEval)); IfFailRet(iCorEval->CreateValue(type, nullptr, ppValue)); + if (!ptr) + return S_OK; + ToRelease iCorGenValue; IfFailRet((*ppValue)->QueryInterface(IID_ICorDebugGenericValue, (LPVOID *) &iCorGenValue)); return iCorGenValue->SetValue(ptr); @@ -307,6 +310,31 @@ namespace return Status; } + HRESULT GetFrontStackEntryType(ICorDebugType **ppResultType, std::list &evalStack, EvalData &ed, std::string &output) + { + HRESULT Status; + ToRelease iCorValue; + if ((FAILED(Status = ed.pEvaluator->ResolveIdentifiers(ed.pThread, ed.frameLevel, evalStack.front().iCorValue, evalStack.front().identifiers, &iCorValue, ppResultType, ed.evalFlags)) + && !evalStack.front().identifiers.empty()) || iCorValue) + { + std::ostringstream ss; + for (size_t i = 0; i < evalStack.front().identifiers.size(); i++) + { + if (i != 0) + ss << "."; + ss << evalStack.front().identifiers[i]; + } + if(!iCorValue) + output = "error: The type or namespace name '" + ss.str() + "' couldn't be found"; + else + output = "error: '" + ss.str() + "' is a variable but is used like a type"; + if (SUCCEEDED(Status)) + Status = E_FAIL; + } + + return Status; + } + HRESULT GetIndexesFromStack(std::vector &indexes, int dimension, std::list &evalStack, EvalData &ed, std::string &output) { HRESULT Status; @@ -1254,15 +1282,33 @@ namespace HRESULT PredefinedType(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) { + static const CorElementType BasicTypesAlias[] { + ELEMENT_TYPE_BOOLEAN, // Boolean + ELEMENT_TYPE_U1, // Byte + ELEMENT_TYPE_CHAR, // Char + ELEMENT_TYPE_VALUETYPE, // Decimal + ELEMENT_TYPE_R8, // Double + ELEMENT_TYPE_R4, // Float + ELEMENT_TYPE_I4, // Int + ELEMENT_TYPE_I8, // Long + ELEMENT_TYPE_MAX, // Object + ELEMENT_TYPE_I1, // SByte + ELEMENT_TYPE_I2, // Short + ELEMENT_TYPE_MAX, // String + ELEMENT_TYPE_U2, // UShort + ELEMENT_TYPE_U4, // UInt + ELEMENT_TYPE_U8 // ULong + }; + // TODO uint32_t Flags = ((FormatFI*)pArguments)->Flags; - // TODO int32_t Int = ((FormatFI*)pArguments)->Int; - return E_NOTIMPL; - } + int32_t Int = ((FormatFI*)pArguments)->Int; - HRESULT QualifiedName(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) - { - // TODO uint32_t Flags = ((FormatF*)pArguments)->Flags; - return E_NOTIMPL; + evalStack.emplace_front(); + + if (BasicTypesAlias[Int] == ELEMENT_TYPE_VALUETYPE) + return CreateValueType(ed.pEvalWaiter, ed.pThread, ed.iCorDecimalClass, &evalStack.front().iCorValuePredefined, nullptr); + else + return CreatePrimitiveValue(ed.pThread, &evalStack.front().iCorValuePredefined, BasicTypesAlias[Int], nullptr); } HRESULT AliasQualifiedName(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) @@ -1323,6 +1369,11 @@ namespace return S_OK; } + HRESULT QualifiedName(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) + { + return SimpleMemberAccessExpression(evalStack, pArguments, output, ed); + } + HRESULT PointerMemberAccessExpression(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) { // TODO uint32_t Flags = ((FormatF*)pArguments)->Flags; @@ -1504,10 +1555,63 @@ namespace HRESULT SizeOfExpression(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) { - // TODO uint32_t Flags = ((FormatF*)pArguments)->Flags; - return E_NOTIMPL; + assert(evalStack.size() > 0); + HRESULT Status; + uint32_t size = 0; + PVOID szPtr = &size; + + if (evalStack.front().iCorValuePredefined) + { + // predefined type + CorElementType elType; + IfFailRet(evalStack.front().iCorValuePredefined->GetType(&elType)); + if(elType == ELEMENT_TYPE_CLASS) + { + ToRelease iCorValue; + IfFailRet(DereferenceAndUnboxValue(evalStack.front().iCorValuePredefined, &iCorValue, nullptr)); + IfFailRet(iCorValue->GetSize(&size)); + } + else + { + IfFailRet(evalStack.front().iCorValuePredefined->GetSize(&size)); + } + } + else + { + ToRelease iCorType; + ToRelease iCorValueRef, iCorValue; + + IfFailRet(GetFrontStackEntryType(&iCorType, evalStack, ed, output)); + if(iCorType) + { + CorElementType elType; + IfFailRet(iCorType->GetType(&elType)); + if (elType == ELEMENT_TYPE_VALUETYPE) + { + // user defined type (structure) + ToRelease iCorClass; + + IfFailRet(iCorType->GetClass(&iCorClass)); + IfFailRet(CreateValueType(ed.pEvalWaiter, ed.pThread, iCorClass, &iCorValueRef, nullptr)); + IfFailRet(DereferenceAndUnboxValue(iCorValueRef, &iCorValue, nullptr)); + IfFailRet(iCorValue->GetSize(&size)); + } + else + { + return E_INVALIDARG; + } + } + else + { + // TODO other cases + return E_NOTIMPL; + } + } + evalStack.front().ResetEntry(); + return CreatePrimitiveValue(ed.pThread, &evalStack.front().iCorValue, ELEMENT_TYPE_U4, szPtr); } + HRESULT TypeOfExpression(std::list &evalStack, PVOID pArguments, std::string &output, EvalData &ed) { // TODO uint32_t Flags = ((FormatF*)pArguments)->Flags; diff --git a/src/debugger/evalstackmachine.h b/src/debugger/evalstackmachine.h index d30e721..78a31f1 100644 --- a/src/debugger/evalstackmachine.h +++ b/src/debugger/evalstackmachine.h @@ -29,6 +29,8 @@ struct EvalStackEntry std::vector identifiers; // Resolved to value identifiers. ToRelease iCorValue; + // Predefined types values + ToRelease iCorValuePredefined; // Prevent future binding in case of conditional access with nulled object (`a?.b`, `a?[1]`, ...). // Note, this state could be related to iCorValue only (iCorValue must be checked for null first). bool preventBinding; @@ -42,6 +44,7 @@ struct EvalStackEntry { identifiers.clear(); iCorValue.Free(); + iCorValuePredefined.Free(); preventBinding = false; if (!skipLiteral) literal = false; diff --git a/src/managed/StackMachine.cs b/src/managed/StackMachine.cs index 016f429..93a851b 100644 --- a/src/managed/StackMachine.cs +++ b/src/managed/StackMachine.cs @@ -658,11 +658,11 @@ namespace NetCoreDbg case SyntaxKind.CharacterLiteralExpression: // 1 wchar stackMachineProgram.Commands.Add(new TwoOperandCommand(node.Kind(), CurrentScopeFlags.Peek(), TypeAlias[node.GetFirstToken().Value.GetType()], node.GetFirstToken().Value)); break; -/* TODO + case SyntaxKind.PredefinedType: stackMachineProgram.Commands.Add(new OneOperandCommand(node.Kind(), CurrentScopeFlags.Peek(), TypeKindAlias[node.GetFirstToken().Kind()])); break; -*/ + // skip, in case of stack machine program creation we don't use this kinds directly case SyntaxKind.Argument: case SyntaxKind.BracketedArgumentList: @@ -705,9 +705,9 @@ namespace NetCoreDbg case SyntaxKind.LessThanExpression: case SyntaxKind.GreaterThanOrEqualExpression: case SyntaxKind.LessThanOrEqualExpression: + case SyntaxKind.QualifiedName: /* TODO - case SyntaxKind.QualifiedName: case SyntaxKind.AliasQualifiedName: case SyntaxKind.ConditionalExpression: case SyntaxKind.PointerMemberAccessExpression: @@ -718,7 +718,9 @@ namespace NetCoreDbg case SyntaxKind.PostIncrementExpression: case SyntaxKind.PreDecrementExpression: case SyntaxKind.PostDecrementExpression: +*/ case SyntaxKind.SizeOfExpression: +/* case SyntaxKind.TypeOfExpression: case SyntaxKind.CoalesceExpression: */ diff --git a/test-suite/MITestSizeof/MITestSizeof.csproj b/test-suite/MITestSizeof/MITestSizeof.csproj new file mode 100644 index 0000000..2005951 --- /dev/null +++ b/test-suite/MITestSizeof/MITestSizeof.csproj @@ -0,0 +1,13 @@ + + + + + + + + Exe + netcoreapp3.1 + true + + + diff --git a/test-suite/MITestSizeof/Program.cs b/test-suite/MITestSizeof/Program.cs new file mode 100644 index 0000000..4f57521 --- /dev/null +++ b/test-suite/MITestSizeof/Program.cs @@ -0,0 +1,279 @@ +using System; +using System.IO; + +using NetcoreDbgTest; +using NetcoreDbgTest.MI; +using NetcoreDbgTest.Script; + +namespace NetcoreDbgTest.Script +{ + class Context + { + public void Prepare(string caller_trace) + { + Assert.Equal(MIResultClass.Done, + MIDebugger.Request("-file-exec-and-symbols " + ControlInfo.CorerunPath).Class, + @"__FILE__:__LINE__"+"\n"+caller_trace); + + Assert.Equal(MIResultClass.Done, + MIDebugger.Request("-exec-arguments " + ControlInfo.TargetAssemblyPath).Class, + @"__FILE__:__LINE__"+"\n"+caller_trace); + + Assert.Equal(MIResultClass.Running, + MIDebugger.Request("-exec-run").Class, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void EnableBreakpoint(string caller_trace, string bpName) + { + Breakpoint bp = ControlInfo.Breakpoints[bpName]; + + Assert.Equal(BreakpointType.Line, bp.Type, @"__FILE__:__LINE__"+"\n"+caller_trace); + + var lbp = (LineBreakpoint)bp; + + Assert.Equal(MIResultClass.Done, + MIDebugger.Request("-break-insert -f " + lbp.FileName + ":" + lbp.NumLine).Class, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void CalcAndCheckExpression(string caller_trace, string ExpectedResult, string expr) + { + var res = MIDebugger.Request("-var-create - * \"" + expr + "\""); + + Assert.Equal(MIResultClass.Done, res.Class, @"__FILE__:__LINE__"+"\n"+caller_trace); + Assert.Equal(ExpectedResult, ((MIConst)res["value"]).CString, @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void CheckErrorAtRequest(string caller_trace, string Expression, string errMsgStart) + { + var res = MIDebugger.Request(String.Format("-var-create - * \"{0}\"", Expression)); + Assert.Equal(MIResultClass.Error, res.Class, @"__FILE__:__LINE__"+"\n"+caller_trace); + Assert.True(((MIConst)res["msg"]).CString.StartsWith(errMsgStart), @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void GetResultAsString(string caller_trace, string expr, out string strRes) + { + var res = MIDebugger.Request("-var-create - * \"" + expr + "\""); + Assert.Equal(MIResultClass.Done, res.Class, @"__FILE__:__LINE__"+"\n" + caller_trace); + strRes = ((MIConst)res["value"]).CString; + } + + public void WasEntryPointHit(string caller_trace) + { + Func filter = (record) => { + if (!IsStoppedEvent(record)) { + return false; + } + + var output = ((MIAsyncRecord)record).Output; + var reason = (MIConst)output["reason"]; + + if (reason.CString != "entry-point-hit") { + return false; + } + + var frame = (MITuple)output["frame"]; + var func = (MIConst)frame["func"]; + if (func.CString == ControlInfo.TestName + ".Program.Main()") { + return true; + } + + return false; + }; + + Assert.True(MIDebugger.IsEventReceived(filter), @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void WasBreakpointHit(string caller_trace, string bpName) + { + var bp = (LineBreakpoint)ControlInfo.Breakpoints[bpName]; + + Func filter = (record) => { + if (!IsStoppedEvent(record)) { + return false; + } + + var output = ((MIAsyncRecord)record).Output; + var reason = (MIConst)output["reason"]; + + if (reason.CString != "breakpoint-hit") { + return false; + } + + var frame = (MITuple)output["frame"]; + var fileName = (MIConst)frame["file"]; + var line = ((MIConst)frame["line"]).Int; + + if (fileName.CString == bp.FileName && + line == bp.NumLine) { + return true; + } + + return false; + }; + + Assert.True(MIDebugger.IsEventReceived(filter), + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void WasExit(string caller_trace) + { + Func filter = (record) => { + if (!IsStoppedEvent(record)) { + return false; + } + + var output = ((MIAsyncRecord)record).Output; + var reason = (MIConst)output["reason"]; + + if (reason.CString != "exited") { + return false; + } + + var exitCode = (MIConst)output["exit-code"]; + + if (exitCode.CString == "0") { + return true; + } + + return false; + }; + + Assert.True(MIDebugger.IsEventReceived(filter), @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void DebuggerExit(string caller_trace) + { + Assert.Equal(MIResultClass.Exit, + MIDebugger.Request("-gdb-exit").Class, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + bool IsStoppedEvent(MIOutOfBandRecord record) + { + if (record.Type != MIOutOfBandRecordType.Async) { + return false; + } + + var asyncRecord = (MIAsyncRecord)record; + + if (asyncRecord.Class != MIAsyncRecordClass.Exec || + asyncRecord.Output.Class != MIAsyncOutputClass.Stopped) { + return false; + } + + return true; + } + + public void Continue(string caller_trace) + { + Assert.Equal(MIResultClass.Running, + MIDebugger.Request("-exec-continue").Class, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public Context(ControlInfo controlInfo, NetcoreDbgTestCore.DebuggerClient debuggerClient) + { + ControlInfo = controlInfo; + MIDebugger = new MIDebugger(debuggerClient); + } + + ControlInfo ControlInfo; + MIDebugger MIDebugger; + } +} + +namespace MITestSizeof +{ + public struct Point + { + public Point(byte tag, decimal x, decimal y) => (Tag, X, Y) = (tag, x, y); + + public decimal X { get; } + public decimal Y { get; } + public byte Tag { get; } + } + + + class Program + { + static void Main(string[] args) + { + Label.Checkpoint("init", "expression_test1", (Object context) => { + Context Context = (Context)context; + Context.Prepare(@"__FILE__:__LINE__"); + Context.WasEntryPointHit(@"__FILE__:__LINE__"); + Context.EnableBreakpoint(@"__FILE__:__LINE__", "BREAK1"); + Context.Continue(@"__FILE__:__LINE__"); + }); + + int a = 10; + TestStruct tc = new TestStruct(a, 11); + string str1 = "string1"; + uint c; + unsafe { c = (uint)sizeof(Point); } + uint d = c; Label.Breakpoint("BREAK1"); + + Label.Checkpoint("expression_test1", "finish", (Object context) => { + Context Context = (Context)context; + Context.WasBreakpointHit(@"__FILE__:__LINE__", "BREAK1"); + + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(bool).ToString(), "sizeof(bool)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(byte).ToString(), "sizeof(byte)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(sbyte).ToString(), "sizeof(sbyte)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(char).ToString(), "sizeof(char)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(int).ToString(), "sizeof(int)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(uint).ToString(), "sizeof(uint)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(long).ToString(), "sizeof(long)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(ulong).ToString(), "sizeof(ulong)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(float).ToString(), "sizeof(float)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(double).ToString(), "sizeof(double)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(decimal).ToString(), "sizeof(decimal)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Boolean).ToString(), "sizeof(System.Boolean)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Byte).ToString(), "sizeof(System.Byte)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Char).ToString(), "sizeof(System.Char)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Decimal).ToString(), "sizeof(System.Decimal)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Double).ToString(), "sizeof(System.Double)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Int16).ToString(), "sizeof(System.Int16)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Int32).ToString(), "sizeof(System.Int32)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Int64).ToString(), "sizeof(System.Int64)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.SByte).ToString(), "sizeof(System.SByte)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.Single).ToString(), "sizeof(System.Single)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.UInt16).ToString(), "sizeof(System.UInt16)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.UInt32).ToString(), "sizeof(System.UInt32)"); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", sizeof(System.UInt64).ToString(), "sizeof(System.UInt64)"); + string ss1; + Context.GetResultAsString(@"__FILE__:__LINE__", "sizeof(Point)", out ss1); + Context.CalcAndCheckExpression(@"__FILE__:__LINE__", ss1, "c"); + + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "sizeof(a)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "sizeof(tc)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "sizeof(str1)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "sizeof(abcd)", "error: The type or namespace name"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "sizeof(Program)", "Error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "sizeof(tc.a)", ""); + + Context.Continue(@"__FILE__:__LINE__"); + }); + + Label.Checkpoint("finish", "", (Object context) => { + Context Context = (Context)context; + Context.WasExit(@"__FILE__:__LINE__"); + Context.DebuggerExit(@"__FILE__:__LINE__"); + }); + } + + struct TestStruct + { + public int a; + public int b; + + public TestStruct(int x, int y) + { + a = x; + b = y; + } + } + } +} diff --git a/test-suite/NetcoreDbgTest/ControlScript.cs b/test-suite/NetcoreDbgTest/ControlScript.cs index 3a33d69..9a1d477 100644 --- a/test-suite/NetcoreDbgTest/ControlScript.cs +++ b/test-suite/NetcoreDbgTest/ControlScript.cs @@ -198,6 +198,7 @@ namespace NetcoreDbgTestCore Compilation CompileTree(SyntaxTree tree) { + //var CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) var compilation = CSharpCompilation.Create( "ControlScript", new SyntaxTree[] {tree}, diff --git a/test-suite/VSCodeTestSizeof/Program.cs b/test-suite/VSCodeTestSizeof/Program.cs new file mode 100644 index 0000000..98b7497 --- /dev/null +++ b/test-suite/VSCodeTestSizeof/Program.cs @@ -0,0 +1,345 @@ +using System; +using System.IO; +using System.Collections.Generic; + +using NetcoreDbgTest; +using NetcoreDbgTest.VSCode; +using NetcoreDbgTest.Script; + +using Newtonsoft.Json; + +namespace NetcoreDbgTest.Script +{ + class Context + { + public void PrepareStart(string caller_trace) + { + InitializeRequest initializeRequest = new InitializeRequest(); + initializeRequest.arguments.clientID = "vscode"; + initializeRequest.arguments.clientName = "Visual Studio Code"; + initializeRequest.arguments.adapterID = "coreclr"; + initializeRequest.arguments.pathFormat = "path"; + initializeRequest.arguments.linesStartAt1 = true; + initializeRequest.arguments.columnsStartAt1 = true; + initializeRequest.arguments.supportsVariableType = true; + initializeRequest.arguments.supportsVariablePaging = true; + initializeRequest.arguments.supportsRunInTerminalRequest = true; + initializeRequest.arguments.locale = "en-us"; + Assert.True(VSCodeDebugger.Request(initializeRequest).Success, + @"__FILE__:__LINE__"+"\n"+caller_trace); + + LaunchRequest launchRequest = new LaunchRequest(); + launchRequest.arguments.name = ".NET Core Launch (console) with pipeline"; + launchRequest.arguments.type = "coreclr"; + launchRequest.arguments.preLaunchTask = "build"; + launchRequest.arguments.program = ControlInfo.TargetAssemblyPath; + launchRequest.arguments.cwd = ""; + launchRequest.arguments.console = "internalConsole"; + launchRequest.arguments.stopAtEntry = true; + launchRequest.arguments.internalConsoleOptions = "openOnSessionStart"; + launchRequest.arguments.__sessionId = Guid.NewGuid().ToString(); + Assert.True(VSCodeDebugger.Request(launchRequest).Success, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void PrepareEnd(string caller_trace) + { + ConfigurationDoneRequest configurationDoneRequest = new ConfigurationDoneRequest(); + Assert.True(VSCodeDebugger.Request(configurationDoneRequest).Success, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void WasEntryPointHit(string caller_trace) + { + Func filter = (resJSON) => { + if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "stopped") + && VSCodeDebugger.isResponseContainProperty(resJSON, "reason", "entry")) { + threadId = Convert.ToInt32(VSCodeDebugger.GetResponsePropertyValue(resJSON, "threadId")); + return true; + } + return false; + }; + + Assert.True(VSCodeDebugger.IsEventReceived(filter), + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void WasExit(string caller_trace) + { + bool wasExited = false; + int ?exitCode = null; + bool wasTerminated = false; + + Func filter = (resJSON) => { + if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "exited")) { + wasExited = true; + ExitedEvent exitedEvent = JsonConvert.DeserializeObject(resJSON); + exitCode = exitedEvent.body.exitCode; + } + if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "terminated")) { + wasTerminated = true; + } + if (wasExited && exitCode == 0 && wasTerminated) + return true; + + return false; + }; + + Assert.True(VSCodeDebugger.IsEventReceived(filter), + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void DebuggerExit(string caller_trace) + { + DisconnectRequest disconnectRequest = new DisconnectRequest(); + disconnectRequest.arguments = new DisconnectArguments(); + disconnectRequest.arguments.restart = false; + Assert.True(VSCodeDebugger.Request(disconnectRequest).Success, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void AddBreakpoint(string caller_trace, string bpName, string Condition = null) + { + Breakpoint bp = ControlInfo.Breakpoints[bpName]; + Assert.Equal(BreakpointType.Line, bp.Type, + @"__FILE__:__LINE__"+"\n"+caller_trace); + var lbp = (LineBreakpoint)bp; + + BreakpointSourceName = lbp.FileName; + BreakpointList.Add(new SourceBreakpoint(lbp.NumLine, Condition)); + BreakpointLines.Add(lbp.NumLine); + } + + public void SetBreakpoints(string caller_trace) + { + SetBreakpointsRequest setBreakpointsRequest = new SetBreakpointsRequest(); + setBreakpointsRequest.arguments.source.name = BreakpointSourceName; + // NOTE this code works only with one source file + setBreakpointsRequest.arguments.source.path = ControlInfo.SourceFilesPath; + setBreakpointsRequest.arguments.lines.AddRange(BreakpointLines); + setBreakpointsRequest.arguments.breakpoints.AddRange(BreakpointList); + setBreakpointsRequest.arguments.sourceModified = false; + Assert.True(VSCodeDebugger.Request(setBreakpointsRequest).Success, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void WasBreakpointHit(string caller_trace, string bpName) + { + Func filter = (resJSON) => { + if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "stopped") + && VSCodeDebugger.isResponseContainProperty(resJSON, "reason", "breakpoint")) { + threadId = Convert.ToInt32(VSCodeDebugger.GetResponsePropertyValue(resJSON, "threadId")); + return true; + } + return false; + }; + + Assert.True(VSCodeDebugger.IsEventReceived(filter), @"__FILE__:__LINE__"+"\n"+caller_trace); + + StackTraceRequest stackTraceRequest = new StackTraceRequest(); + stackTraceRequest.arguments.threadId = threadId; + stackTraceRequest.arguments.startFrame = 0; + stackTraceRequest.arguments.levels = 20; + var ret = VSCodeDebugger.Request(stackTraceRequest); + Assert.True(ret.Success, @"__FILE__:__LINE__"+"\n"+caller_trace); + + Breakpoint breakpoint = ControlInfo.Breakpoints[bpName]; + Assert.Equal(BreakpointType.Line, breakpoint.Type, @"__FILE__:__LINE__"+"\n"+caller_trace); + var lbp = (LineBreakpoint)breakpoint; + + StackTraceResponse stackTraceResponse = + JsonConvert.DeserializeObject(ret.ResponseStr); + + if (stackTraceResponse.body.stackFrames[0].line == lbp.NumLine + && stackTraceResponse.body.stackFrames[0].source.name == lbp.FileName + // NOTE this code works only with one source file + && stackTraceResponse.body.stackFrames[0].source.path == ControlInfo.SourceFilesPath) + return; + + throw new ResultNotSuccessException(@"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void Continue(string caller_trace) + { + ContinueRequest continueRequest = new ContinueRequest(); + continueRequest.arguments.threadId = threadId; + Assert.True(VSCodeDebugger.Request(continueRequest).Success, + @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public Context(ControlInfo controlInfo, NetcoreDbgTestCore.DebuggerClient debuggerClient) + { + ControlInfo = controlInfo; + VSCodeDebugger = new VSCodeDebugger(debuggerClient); + } + + public Int64 DetectFrameId(string caller_trace, string bpName) + { + StackTraceRequest stackTraceRequest = new StackTraceRequest(); + stackTraceRequest.arguments.threadId = threadId; + stackTraceRequest.arguments.startFrame = 0; + stackTraceRequest.arguments.levels = 20; + var ret = VSCodeDebugger.Request(stackTraceRequest); + Assert.True(ret.Success, @"__FILE__:__LINE__"+"\n"+caller_trace); + + Breakpoint breakpoint = ControlInfo.Breakpoints[bpName]; + Assert.Equal(BreakpointType.Line, breakpoint.Type, @"__FILE__:__LINE__"+"\n"+caller_trace); + var lbp = (LineBreakpoint)breakpoint; + + StackTraceResponse stackTraceResponse = + JsonConvert.DeserializeObject(ret.ResponseStr); + + if (stackTraceResponse.body.stackFrames[0].line == lbp.NumLine + && stackTraceResponse.body.stackFrames[0].source.name == lbp.FileName + // NOTE this code works only with one source file + && stackTraceResponse.body.stackFrames[0].source.path == ControlInfo.SourceFilesPath) + return stackTraceResponse.body.stackFrames[0].id; + + throw new ResultNotSuccessException(@"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void GetAndCheckValue(string caller_trace, Int64 frameId, string ExpectedResult, string ExpectedType, string Expression) + { + EvaluateRequest evaluateRequest = new EvaluateRequest(); + evaluateRequest.arguments.expression = Expression; + evaluateRequest.arguments.frameId = frameId; + var ret = VSCodeDebugger.Request(evaluateRequest); + Assert.True(ret.Success, @"__FILE__:__LINE__"+"\n"+caller_trace); + + EvaluateResponse evaluateResponse = + JsonConvert.DeserializeObject(ret.ResponseStr); + + Assert.Equal(ExpectedResult, evaluateResponse.body.result, @"__FILE__:__LINE__"+"\n"+caller_trace); + Assert.Equal(ExpectedType, evaluateResponse.body.type, @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void CheckErrorAtRequest(string caller_trace, Int64 frameId, string Expression, string errMsgStart) + { + EvaluateRequest evaluateRequest = new EvaluateRequest(); + evaluateRequest.arguments.expression = Expression; + evaluateRequest.arguments.frameId = frameId; + var ret = VSCodeDebugger.Request(evaluateRequest); + Assert.False(ret.Success, @"__FILE__:__LINE__"+"\n"+caller_trace); + + EvaluateResponse evaluateResponse = + JsonConvert.DeserializeObject(ret.ResponseStr); + + Assert.True(evaluateResponse.message.StartsWith(errMsgStart), @"__FILE__:__LINE__"+"\n"+caller_trace); + } + + public void GetResultAsString(string caller_trace, Int64 frameId, string expr, out string strRes) + { + EvaluateRequest evaluateRequest = new EvaluateRequest(); + evaluateRequest.arguments.expression = expr; + evaluateRequest.arguments.frameId = frameId; + var ret = VSCodeDebugger.Request(evaluateRequest); + Assert.True(ret.Success, @"__FILE__:__LINE__"+"\n"+caller_trace); + EvaluateResponse evaluateResponse = JsonConvert.DeserializeObject(ret.ResponseStr); + strRes = evaluateResponse.body.result; + } + + ControlInfo ControlInfo; + VSCodeDebugger VSCodeDebugger; + int threadId = -1; + string BreakpointSourceName; + List BreakpointList = new List(); + List BreakpointLines = new List(); + } +} + +namespace VSCodeTestSizeof +{ + public struct Point + { + public Point(byte tag, decimal x, decimal y) => (Tag, X, Y) = (tag, x, y); + + public decimal X { get; } + public decimal Y { get; } + public byte Tag { get; } + } + + class Program + { + static void Main(string[] args) + { + // first checkpoint (initialization) must provide "init" as id + Label.Checkpoint("init", "bp_test", (Object context) => { + Context Context = (Context)context; + Context.PrepareStart(@"__FILE__:__LINE__"); + Context.AddBreakpoint(@"__FILE__:__LINE__", "BREAK1"); + Context.SetBreakpoints(@"__FILE__:__LINE__"); + Context.PrepareEnd(@"__FILE__:__LINE__"); + Context.WasEntryPointHit(@"__FILE__:__LINE__"); + Context.Continue(@"__FILE__:__LINE__"); + }); + + int a = 10; + TestStruct tc = new TestStruct(a, 11); + string str1 = "string1"; + uint c; + unsafe { c = (uint)sizeof(Point); } + uint d = c; Label.Breakpoint("BREAK1"); + + Label.Checkpoint("bp_test", "finish", (Object context) => { + Context Context = (Context)context; + Context.WasBreakpointHit(@"__FILE__:__LINE__", "BREAK1"); + Int64 frameId = Context.DetectFrameId(@"__FILE__:__LINE__", "BREAK1"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(bool).ToString(), "uint", "sizeof(bool)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(byte).ToString(), "uint", "sizeof(byte)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(sbyte).ToString(), "uint", "sizeof(sbyte)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(char).ToString(), "uint", "sizeof(char)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(int).ToString(), "uint", "sizeof(int)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(uint).ToString(), "uint", "sizeof(uint)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(long).ToString(), "uint", "sizeof(long)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(ulong).ToString(), "uint", "sizeof(ulong)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(float).ToString(), "uint", "sizeof(float)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(double).ToString(), "uint", "sizeof(double)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(decimal).ToString(), "uint", "sizeof(decimal)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Boolean).ToString(), "uint", "sizeof(System.Boolean)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Byte).ToString(), "uint", "sizeof(System.Byte)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Char).ToString(), "uint", "sizeof(System.Char)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Decimal).ToString(), "uint", "sizeof(System.Decimal)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Double).ToString(), "uint", "sizeof(System.Double)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Int16).ToString(), "uint", "sizeof(System.Int16)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Int32).ToString(), "uint", "sizeof(System.Int32)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Int64).ToString(), "uint", "sizeof(System.Int64)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.SByte).ToString(), "uint", "sizeof(System.SByte)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.Single).ToString(), "uint", "sizeof(System.Single)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.UInt16).ToString(), "uint", "sizeof(System.UInt16)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.UInt32).ToString(), "uint", "sizeof(System.UInt32)"); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, sizeof(System.UInt64).ToString(), "uint", "sizeof(System.UInt64)"); + string ss1; + Context.GetResultAsString(@"__FILE__:__LINE__", frameId, "sizeof(Point)", out ss1); + Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, ss1, "uint", "c"); + + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "sizeof(a)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "sizeof(tc)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "sizeof(str1)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "sizeof(abcd)", "error: The type or namespace name"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "sizeof(Program)", "error:"); + Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "sizeof(tc.a)", ""); + + Context.Continue(@"__FILE__:__LINE__"); + }); + + // last checkpoint must provide "finish" as id or empty string ("") as next checkpoint id + Label.Checkpoint("finish", "", (Object context) => { + Context Context = (Context)context; + Context.WasExit(@"__FILE__:__LINE__"); + Context.DebuggerExit(@"__FILE__:__LINE__"); + }); + } + + struct TestStruct + { + public int a; + public int b; + + public TestStruct(int x, int y) + { + a = x; + b = y; + } + } + } +} diff --git a/test-suite/VSCodeTestSizeof/VSCodeTestSizeof.csproj b/test-suite/VSCodeTestSizeof/VSCodeTestSizeof.csproj new file mode 100644 index 0000000..2005951 --- /dev/null +++ b/test-suite/VSCodeTestSizeof/VSCodeTestSizeof.csproj @@ -0,0 +1,13 @@ + + + + + + + + Exe + netcoreapp3.1 + true + + + diff --git a/test-suite/XunitTests/LocalTest.cs b/test-suite/XunitTests/LocalTest.cs index e402e9a..8b539c5 100644 --- a/test-suite/XunitTests/LocalTest.cs +++ b/test-suite/XunitTests/LocalTest.cs @@ -44,6 +44,7 @@ namespace XUnitTests [InlineData("MITestNoJMCBreakpoint", "Program.cs")] [InlineData("MITestNoJMCAsyncStepping", "Program.cs")] [InlineData("MITestNoJMCExceptionBreakpoint", "Program.cs")] + [InlineData("MITestSizeof", "Program.cs")] [InlineData("VSCodeExampleTest", "Program.cs")] [InlineData("VSCodeTestBreakpoint", "Program.cs")] [InlineData("VSCodeTestFuncBreak", "Program.cs")] @@ -67,6 +68,7 @@ namespace XUnitTests [InlineData("VSCodeTestNoJMCAsyncStepping", "Program.cs")] [InlineData("VSCodeTestExceptionBreakpoint", "Program.cs")] [InlineData("VSCodeTestNoJMCExceptionBreakpoint", "Program.cs")] + [InlineData("VSCodeTestSizeof", "Program.cs")] public void Run(string testCaseName, string testCourceList) { // Explicit encoding setup, since system console encoding could be not utf8 (Windows OS). diff --git a/test-suite/XunitTests/XunitTests.csproj b/test-suite/XunitTests/XunitTests.csproj index 579d35e..41db668 100644 --- a/test-suite/XunitTests/XunitTests.csproj +++ b/test-suite/XunitTests/XunitTests.csproj @@ -65,6 +65,8 @@ + + diff --git a/test-suite/run_tests.ps1 b/test-suite/run_tests.ps1 index 34ddea1..5923f9c 100644 --- a/test-suite/run_tests.ps1 +++ b/test-suite/run_tests.ps1 @@ -28,6 +28,7 @@ $ALL_TEST_NAMES = @( "MITestNoJMCBreakpoint" "MITestNoJMCAsyncStepping" "MITestNoJMCExceptionBreakpoint" + "MITestSizeof" "VSCodeExampleTest" "VSCodeTestBreakpoint" "VSCodeTestFuncBreak" @@ -51,6 +52,7 @@ $ALL_TEST_NAMES = @( "VSCodeTestNoJMCAsyncStepping" "VSCodeTestExceptionBreakpoint" "VSCodeTestNoJMCExceptionBreakpoint" + "VSCodeTestSizeof" ) # Skipped tests: diff --git a/test-suite/run_tests.sh b/test-suite/run_tests.sh index 006d6d3..fe02536 100755 --- a/test-suite/run_tests.sh +++ b/test-suite/run_tests.sh @@ -29,6 +29,7 @@ ALL_TEST_NAMES=( "MITestNoJMCBreakpoint" "MITestNoJMCAsyncStepping" "MITestNoJMCExceptionBreakpoint" + "MITestSizeof" "VSCodeExampleTest" "VSCodeTestBreakpoint" "VSCodeTestFuncBreak" @@ -52,6 +53,7 @@ ALL_TEST_NAMES=( "VSCodeTestNoJMCAsyncStepping" "VSCodeTestExceptionBreakpoint" "VSCodeTestNoJMCExceptionBreakpoint" + "VSCodeTestSizeof" ) # Skipped tests: diff --git a/test-suite/sdb_run_tests.ps1 b/test-suite/sdb_run_tests.ps1 index dd500f7..1dcd788 100644 --- a/test-suite/sdb_run_tests.ps1 +++ b/test-suite/sdb_run_tests.ps1 @@ -27,6 +27,7 @@ $ALL_TEST_NAMES = @( "MITestNoJMCBreakpoint" "MITestNoJMCAsyncStepping" "MITestNoJMCExceptionBreakpoint" + "MITestSizeof" "VSCodeExampleTest" "VSCodeTestBreakpoint" "VSCodeTestFuncBreak" @@ -47,6 +48,7 @@ $ALL_TEST_NAMES = @( "VSCodeTestNoJMCAsyncStepping" "VSCodeTestExceptionBreakpoint" "VSCodeTestNoJMCExceptionBreakpoint" + "VSCodeTestSizeof" ) # Skipped tests: diff --git a/test-suite/sdb_run_tests.sh b/test-suite/sdb_run_tests.sh index b52cd5f..25d6e5f 100755 --- a/test-suite/sdb_run_tests.sh +++ b/test-suite/sdb_run_tests.sh @@ -55,6 +55,7 @@ ALL_TEST_NAMES=( "MITestNoJMCBreakpoint" "MITestNoJMCAsyncStepping" "MITestNoJMCExceptionBreakpoint" + "MITestSizeof" "VSCodeExampleTest" "VSCodeTestBreakpoint" "VSCodeTestFuncBreak" @@ -75,6 +76,7 @@ ALL_TEST_NAMES=( "VSCodeTestNoJMCNoFilterStepping" "VSCodeTestNoJMCBreakpoint" "VSCodeTestNoJMCAsyncStepping" + "VSCodeTestSizeof" ) # Skipped tests: diff --git a/test-suite/test-suite.sln b/test-suite/test-suite.sln index 23599e3..464ef61 100644 --- a/test-suite/test-suite.sln +++ b/test-suite/test-suite.sln @@ -60,6 +60,7 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestExitCode", "MITestExitCode\MITestExitCode.csproj", "{9308CF34-12C5-4D5B-A318-00AD7AC1907A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestExitCode", "VSCodeTestExitCode\VSCodeTestExitCode.csproj", "{045EE2A3-F595-4D40-8E1A-734CA9CEB10C}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestEvalNotEnglish", "MITestEvalNotEnglish\MITestEvalNotEnglish.csproj", "{76D789CF-9499-4A12-9128-7378592B7BDC}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestEvalNotEnglish", "VSCodeTestEvalNotEnglish\VSCodeTestEvalNotEnglish.csproj", "{5FE6BDFF-AD0E-4E1C-A596-6D583D0777BC}" @@ -67,6 +68,7 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITest中文目录", "MITest中文目录\MITest中文目录.csproj", "{6B76C4A1-D871-4A78-B284-FE8E2FCBA10D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTest中文目录", "VSCodeTest中文目录\VSCodeTest中文目录.csproj", "{56BFF745-3A77-44BF-B068-3E13901295A1}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestSrcBreakpointResolve", "MITestSrcBreakpointResolve\MITestSrcBreakpointResolve.csproj", "{81372498-2551-49D6-8A36-4F57C4985E5E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestSrcBreakpointResolve", "VSCodeTestSrcBreakpointResolve\VSCodeTestSrcBreakpointResolve.csproj", "{C4B66CFD-47AA-4B41-BE26-B6FE2282FF09}" @@ -76,10 +78,11 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestEnum", "MITestEnum\MITestEnum.csproj", "{D52DD1E9-42C9-4378-B505-C94C6B282C49}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestEnum", "VSCodeTestEnum\VSCodeTestEnum.csproj", "{751C9FDC-5992-4734-ABD0-126148F3818D}" -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestAsyncStepping", "VSCodeTestAsyncStepping\VSCodeTestAsyncStepping.csproj", "{CDC2D04E-9433-4D2F-9A77-1839982F6834}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestAsyncStepping", "MITestAsyncStepping\MITestAsyncStepping.csproj", "{C1400CFC-3087-42E1-B580-DE8A00C3686B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestAsyncStepping", "VSCodeTestAsyncStepping\VSCodeTestAsyncStepping.csproj", "{CDC2D04E-9433-4D2F-9A77-1839982F6834}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestBreak", "VSCodeTestBreak\VSCodeTestBreak.csproj", "{0EB5EE41-E73C-4946-8561-4C2BB0EB26BC}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestBreak", "MITestBreak\MITestBreak.csproj", "{954D72F6-BD7C-40EF-A3CA-DD76D26BC2FD}" @@ -104,6 +107,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestNoJMCExceptionBre EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestExceptionBreakpoint", "VSCodeTestExceptionBreakpoint\VSCodeTestExceptionBreakpoint.csproj", "{1770637A-2007-4E96-A8E5-A32772831AD3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestSizeof", "MITestSizeof\MITestSizeof.csproj", "{8FD648F2-8F88-4030-A622-823BFA1A3E1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestSizeof", "VSCodeTestSizeof\VSCodeTestSizeof.csproj", "{C8053627-4094-4913-8E9D-74AD38DCC39F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -741,5 +748,29 @@ Global {1770637A-2007-4E96-A8E5-A32772831AD3}.Release|x64.Build.0 = Release|Any CPU {1770637A-2007-4E96-A8E5-A32772831AD3}.Release|x86.ActiveCfg = Release|Any CPU {1770637A-2007-4E96-A8E5-A32772831AD3}.Release|x86.Build.0 = Release|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Debug|x64.ActiveCfg = Debug|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Debug|x64.Build.0 = Debug|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Debug|x86.ActiveCfg = Debug|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Debug|x86.Build.0 = Debug|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Release|Any CPU.Build.0 = Release|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Release|x64.ActiveCfg = Release|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Release|x64.Build.0 = Release|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Release|x86.ActiveCfg = Release|Any CPU + {8FD648F2-8F88-4030-A622-823BFA1A3E1C}.Release|x86.Build.0 = Release|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Debug|x64.ActiveCfg = Debug|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Debug|x64.Build.0 = Debug|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Debug|x86.ActiveCfg = Debug|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Debug|x86.Build.0 = Debug|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Release|Any CPU.Build.0 = Release|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Release|x64.ActiveCfg = Release|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Release|x64.Build.0 = Release|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Release|x86.ActiveCfg = Release|Any CPU + {C8053627-4094-4913-8E9D-74AD38DCC39F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection EndGlobal