Fix breakpoint setup for running process without stop.
authorMikhail Kurinnoi <m.kurinnoi@samsung.com>
Fri, 26 Aug 2022 13:33:39 +0000 (16:33 +0300)
committerAlexander Soldatov/Platform Lab /SRR/Staff Engineer/Samsung Electronics <soldatov.a@samsung.com>
Mon, 29 Aug 2022 13:55:36 +0000 (16:55 +0300)
src/debugger/breakpoints.cpp
src/debugger/breakpointutils.cpp
test-suite/MITestBreakpointWithoutStop/MITestBreakpointWithoutStop.csproj [new file with mode: 0644]
test-suite/MITestBreakpointWithoutStop/Program.cs [new file with mode: 0644]
test-suite/VSCodeTestBreakpointWithoutStop/Program.cs [new file with mode: 0644]
test-suite/VSCodeTestBreakpointWithoutStop/VSCodeTestBreakpointWithoutStop.csproj [new file with mode: 0644]
test-suite/run_tests.ps1
test-suite/run_tests.sh
test-suite/sdb_run_tests.ps1
test-suite/sdb_run_tests.sh
test-suite/test-suite.sln

index d4006ede4e281aebf1c71900be935fa7c064aaee..4947ea6fdc7716146d709237743b89cba8f7e1b7 100644 (file)
@@ -144,6 +144,21 @@ HRESULT Breakpoints::ManagedCallbackBreakpoint(ICorDebugThread *pThread, ICorDeb
         return S_FALSE; // S_FALSE - not affect on callback (callback will emit stop event)
     }
 
+    // Don't stop at breakpoint in not JMC code, if possible (error here is not fatal for debug process).
+    // We need this check here, since we can't guarantee this check in SkipBreakpoint().
+    ToRelease<ICorDebugFrame> iCorFrame;
+    ToRelease<ICorDebugFunction> iCorFunction;
+    ToRelease<ICorDebugFunction2> iCorFunction2;
+    BOOL JMCStatus;
+    if (SUCCEEDED(pThread->GetActiveFrame(&iCorFrame)) && iCorFrame != nullptr &&
+        SUCCEEDED(iCorFrame->GetFunction(&iCorFunction)) &&
+        SUCCEEDED(iCorFunction->QueryInterface(IID_ICorDebugFunction2, (LPVOID*) &iCorFunction2)) &&
+        SUCCEEDED(iCorFunction2->GetJMCStatus(&JMCStatus)) &&
+        JMCStatus == FALSE)
+    {
+        return S_OK; // forced to interrupt this callback (breakpoint in not user code, continue process execution)
+    }
+
     if (SUCCEEDED(Status = m_uniqueLineBreakpoints->CheckBreakpointHit(pThread, pBreakpoint, breakpoint)) &&
         Status == S_OK) // S_FALSE - no breakpoint hit
     {
index d1feef02b02892e0497696fe96c24d1fb5454c31..9c99ca7798ec2fcd6c3a6e1def0f2f6987e09253 100644 (file)
@@ -102,8 +102,13 @@ HRESULT SkipBreakpoint(ICorDebugModule *pModule, mdMethodDef methodToken, bool j
     IfFailRet(pModule->GetFunctionFromToken(methodToken, &iCorFunction));\r
     ToRelease<ICorDebugFunction2> iCorFunction2;\r
     IfFailRet(iCorFunction->QueryInterface(IID_ICorDebugFunction2, (LPVOID*) &iCorFunction2));\r
-    BOOL JMCStatus;\r
-    IfFailRet(iCorFunction2->GetJMCStatus(&JMCStatus));\r
+    BOOL JMCStatus = FALSE;\r
+    // In case process was not stopped, GetJMCStatus() could return CORDBG_E_PROCESS_NOT_SYNCHRONIZED or another error code.\r
+    // It is OK, check it as JMC code (pModule have symbols for sure), we will also check JMC status at breakpoint callback itself.\r
+    if (FAILED(iCorFunction2->GetJMCStatus(&JMCStatus)))\r
+    {\r
+        JMCStatus = TRUE;\r
+    }\r
     if (JMCStatus == FALSE)\r
     {\r
         return S_OK; // need skip breakpoint\r
diff --git a/test-suite/MITestBreakpointWithoutStop/MITestBreakpointWithoutStop.csproj b/test-suite/MITestBreakpointWithoutStop/MITestBreakpointWithoutStop.csproj
new file mode 100644 (file)
index 0000000..2512674
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">\r
+\r
+  <ItemGroup>\r
+    <ProjectReference Include="..\NetcoreDbgTest\NetcoreDbgTest.csproj" />\r
+  </ItemGroup>\r
+\r
+  <PropertyGroup>\r
+    <OutputType>Exe</OutputType>\r
+    <TargetFramework>netcoreapp3.1</TargetFramework>\r
+  </PropertyGroup>\r
+\r
+</Project>\r
diff --git a/test-suite/MITestBreakpointWithoutStop/Program.cs b/test-suite/MITestBreakpointWithoutStop/Program.cs
new file mode 100644 (file)
index 0000000..e7831dc
--- /dev/null
@@ -0,0 +1,224 @@
+using System;\r
+using System.IO;\r
+using System.Threading;\r
+\r
+using NetcoreDbgTest;\r
+using NetcoreDbgTest.MI;\r
+using NetcoreDbgTest.Script;\r
+\r
+namespace NetcoreDbgTest.Script\r
+{\r
+    class Context\r
+    {\r
+        public void Prepare(string caller_trace)\r
+        {\r
+            Assert.Equal(MIResultClass.Done,\r
+                         MIDebugger.Request("-file-exec-and-symbols " + ControlInfo.CorerunPath).Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+\r
+            Assert.Equal(MIResultClass.Done,\r
+                         MIDebugger.Request("-exec-arguments " + ControlInfo.TargetAssemblyPath).Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+\r
+            Assert.Equal(MIResultClass.Running,\r
+                         MIDebugger.Request("-exec-run").Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        bool IsStoppedEvent(MIOutOfBandRecord record)\r
+        {\r
+            if (record.Type != MIOutOfBandRecordType.Async) {\r
+                return false;\r
+            }\r
+\r
+            var asyncRecord = (MIAsyncRecord)record;\r
+\r
+            if (asyncRecord.Class != MIAsyncRecordClass.Exec ||\r
+                asyncRecord.Output.Class != MIAsyncOutputClass.Stopped) {\r
+                return false;\r
+            }\r
+\r
+            return true;\r
+        }\r
+\r
+        public void WasEntryPointHit(string caller_trace)\r
+        {\r
+            Func<MIOutOfBandRecord, bool> filter = (record) => {\r
+                if (!IsStoppedEvent(record)) {\r
+                    return false;\r
+                }\r
+\r
+                var output = ((MIAsyncRecord)record).Output;\r
+                var reason = (MIConst)output["reason"];\r
+\r
+                if (reason.CString != "entry-point-hit") {\r
+                    return false;\r
+                }\r
+\r
+                var frame = (MITuple)output["frame"];\r
+                var func = (MIConst)frame["func"];\r
+                if (func.CString == ControlInfo.TestName + ".Program.Main()") {\r
+                    return true;\r
+                }\r
+\r
+                return false;\r
+            };\r
+\r
+            Assert.True(MIDebugger.IsEventReceived(filter),\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void WasBreakpointHit(string caller_trace, string bpName)\r
+        {\r
+            var bp = (LineBreakpoint)ControlInfo.Breakpoints[bpName];\r
+\r
+            Func<MIOutOfBandRecord, bool> filter = (record) => {\r
+                if (!IsStoppedEvent(record)) {\r
+                    return false;\r
+                }\r
+\r
+                var output = ((MIAsyncRecord)record).Output;\r
+                var reason = (MIConst)output["reason"];\r
+\r
+                if (reason.CString != "breakpoint-hit") {\r
+                    return false;\r
+                }\r
+\r
+                var frame = (MITuple)output["frame"];\r
+                var fileName = (MIConst)frame["file"];\r
+                var line = ((MIConst)frame["line"]).Int;\r
+\r
+                if (fileName.CString == bp.FileName &&\r
+                    line == bp.NumLine) {\r
+                    return true;\r
+                }\r
+\r
+                return false;\r
+            };\r
+\r
+            Assert.True(MIDebugger.IsEventReceived(filter),\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void WasExit(string caller_trace)\r
+        {\r
+\r
+            Func<MIOutOfBandRecord, bool> filter = (record) => {\r
+                if (!IsStoppedEvent(record)) {\r
+                    return false;\r
+                }\r
+\r
+                var output = ((MIAsyncRecord)record).Output;\r
+                var reason = (MIConst)output["reason"];\r
+\r
+                if (reason.CString != "exited") {\r
+                    return false;\r
+                }\r
+\r
+                var exitCode = (MIConst)output["exit-code"];\r
+\r
+                if (exitCode.CString == "0") {\r
+                    return true;\r
+                }\r
+\r
+                return false;\r
+            };\r
+\r
+            Assert.True(MIDebugger.IsEventReceived(filter),\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void DebuggerExit(string caller_trace)\r
+        {\r
+            Assert.Equal(MIResultClass.Exit,\r
+                         MIDebugger.Request("-gdb-exit").Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void EnableBreakpoint(string caller_trace, string bpName)\r
+        {\r
+            Breakpoint bp = ControlInfo.Breakpoints[bpName];\r
+\r
+            Assert.Equal(BreakpointType.Line, bp.Type, @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+\r
+            var lbp = (LineBreakpoint)bp;\r
+\r
+            Assert.Equal(MIResultClass.Done,\r
+                         MIDebugger.Request("-break-insert -f " + lbp.FileName + ":" + lbp.NumLine).Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void EnableFuncBreakpoint(string caller_trace, string funcName)\r
+        {\r
+            Assert.Equal(MIResultClass.Done,\r
+                         MIDebugger.Request("-break-insert -f " + funcName).Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void Continue(string caller_trace)\r
+        {\r
+            Assert.Equal(MIResultClass.Running,\r
+                         MIDebugger.Request("-exec-continue").Class,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public Context(ControlInfo controlInfo, NetcoreDbgTestCore.DebuggerClient debuggerClient)\r
+        {\r
+            ControlInfo = controlInfo;\r
+            MIDebugger = new MIDebugger(debuggerClient);\r
+        }\r
+\r
+        ControlInfo ControlInfo;\r
+        MIDebugger MIDebugger;\r
+    }\r
+}\r
+\r
+namespace MITestBreakpointWithoutStop\r
+{\r
+    class Program\r
+    {\r
+        static void testfunc()\r
+        {                                                                           Label.Breakpoint("bp_func");\r
+            Console.WriteLine("A breakpoint is set on this testfunc");\r
+        }\r
+\r
+        static void Main(string[] args)\r
+        {\r
+            Label.Checkpoint("init", "bp_test", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.Prepare(@"__FILE__:__LINE__");\r
+                Context.WasEntryPointHit(@"__FILE__:__LINE__");\r
+                Context.Continue(@"__FILE__:__LINE__");\r
+\r
+                System.Threading.Thread.Sleep(5000);\r
+\r
+                Context.EnableBreakpoint(@"__FILE__:__LINE__", "bp");\r
+                Context.EnableFuncBreakpoint(@"__FILE__:__LINE__", "testfunc");\r
+            });\r
+\r
+            Thread.Sleep(15000);\r
+\r
+            Console.WriteLine("A breakpoint \"bp\" is set on this line");           Label.Breakpoint("bp");\r
+\r
+            Label.Checkpoint("bp_test", "bp2_test", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.WasBreakpointHit(@"__FILE__:__LINE__", "bp");\r
+                Context.Continue(@"__FILE__:__LINE__");\r
+            });\r
+\r
+            testfunc();\r
+\r
+            Label.Checkpoint("bp2_test", "finish", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.WasBreakpointHit(@"__FILE__:__LINE__", "bp_func");\r
+                Context.Continue(@"__FILE__:__LINE__");\r
+            });\r
+\r
+            Label.Checkpoint("finish", "", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.WasExit(@"__FILE__:__LINE__");\r
+                Context.DebuggerExit(@"__FILE__:__LINE__");\r
+            });\r
+        }\r
+    }\r
+}\r
diff --git a/test-suite/VSCodeTestBreakpointWithoutStop/Program.cs b/test-suite/VSCodeTestBreakpointWithoutStop/Program.cs
new file mode 100644 (file)
index 0000000..4900512
--- /dev/null
@@ -0,0 +1,251 @@
+using System;\r
+using System.IO;\r
+using System.Threading;\r
+using System.Collections.Generic;\r
+\r
+using NetcoreDbgTest;\r
+using NetcoreDbgTest.VSCode;\r
+using NetcoreDbgTest.Script;\r
+\r
+using Newtonsoft.Json;\r
+\r
+namespace NetcoreDbgTest.Script\r
+{\r
+    class Context\r
+    {\r
+        public void PrepareStart(string caller_trace)\r
+        {\r
+            InitializeRequest initializeRequest = new InitializeRequest();\r
+            initializeRequest.arguments.clientID = "vscode";\r
+            initializeRequest.arguments.clientName = "Visual Studio Code";\r
+            initializeRequest.arguments.adapterID = "coreclr";\r
+            initializeRequest.arguments.pathFormat = "path";\r
+            initializeRequest.arguments.linesStartAt1 = true;\r
+            initializeRequest.arguments.columnsStartAt1 = true;\r
+            initializeRequest.arguments.supportsVariableType = true;\r
+            initializeRequest.arguments.supportsVariablePaging = true;\r
+            initializeRequest.arguments.supportsRunInTerminalRequest = true;\r
+            initializeRequest.arguments.locale = "en-us";\r
+            Assert.True(VSCodeDebugger.Request(initializeRequest).Success,\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+\r
+            LaunchRequest launchRequest = new LaunchRequest();\r
+            launchRequest.arguments.name = ".NET Core Launch (console) with pipeline";\r
+            launchRequest.arguments.type = "coreclr";\r
+            launchRequest.arguments.preLaunchTask = "build";\r
+            launchRequest.arguments.program = ControlInfo.TargetAssemblyPath;\r
+            launchRequest.arguments.cwd = "";\r
+            launchRequest.arguments.console = "internalConsole";\r
+            launchRequest.arguments.stopAtEntry = true;\r
+            launchRequest.arguments.internalConsoleOptions = "openOnSessionStart";\r
+            launchRequest.arguments.__sessionId = Guid.NewGuid().ToString();\r
+            Assert.True(VSCodeDebugger.Request(launchRequest).Success,\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void PrepareEnd(string caller_trace)\r
+        {\r
+            ConfigurationDoneRequest configurationDoneRequest = new ConfigurationDoneRequest();\r
+            Assert.True(VSCodeDebugger.Request(configurationDoneRequest).Success,\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void WasEntryPointHit(string caller_trace)\r
+        {\r
+            Func<string, bool> filter = (resJSON) => {\r
+                if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "stopped")\r
+                    && VSCodeDebugger.isResponseContainProperty(resJSON, "reason", "entry")) {\r
+                    threadId = Convert.ToInt32(VSCodeDebugger.GetResponsePropertyValue(resJSON, "threadId"));\r
+                    return true;\r
+                }\r
+                return false;\r
+            };\r
+\r
+            Assert.True(VSCodeDebugger.IsEventReceived(filter),\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void WasExit(string caller_trace)\r
+        {\r
+            bool wasExited = false;\r
+            int ?exitCode = null;\r
+            bool wasTerminated = false;\r
+\r
+            Func<string, bool> filter = (resJSON) => {\r
+                if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "exited")) {\r
+                    wasExited = true;\r
+                    ExitedEvent exitedEvent = JsonConvert.DeserializeObject<ExitedEvent>(resJSON);\r
+                    exitCode = exitedEvent.body.exitCode;\r
+                }\r
+                if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "terminated")) {\r
+                    wasTerminated = true;\r
+                }\r
+                if (wasExited && exitCode == 0 && wasTerminated)\r
+                    return true;\r
+\r
+                return false;\r
+            };\r
+\r
+            Assert.True(VSCodeDebugger.IsEventReceived(filter),\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void DebuggerExit(string caller_trace)\r
+        {\r
+            DisconnectRequest disconnectRequest = new DisconnectRequest();\r
+            disconnectRequest.arguments = new DisconnectArguments();\r
+            disconnectRequest.arguments.restart = false;\r
+            Assert.True(VSCodeDebugger.Request(disconnectRequest).Success,\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void AddBreakpoint(string caller_trace, string bpName, string Condition = null)\r
+        {\r
+            Breakpoint bp = ControlInfo.Breakpoints[bpName];\r
+            Assert.Equal(BreakpointType.Line, bp.Type,\r
+                         @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+            var lbp = (LineBreakpoint)bp;\r
+\r
+            BreakpointSourceName = lbp.FileName;\r
+            BreakpointList.Add(new SourceBreakpoint(lbp.NumLine, Condition));\r
+            BreakpointLines.Add(lbp.NumLine);\r
+        }\r
+\r
+        public void AddFuncBreakpoint(string funcName, string Condition = null)\r
+        {\r
+            FuncBreakpointList.Add(new FunctionBreakpoint(funcName, Condition));\r
+        }\r
+\r
+        public void SetBreakpoints(string caller_trace)\r
+        {\r
+            SetBreakpointsRequest setBreakpointsRequest = new SetBreakpointsRequest();\r
+            setBreakpointsRequest.arguments.source.name = BreakpointSourceName;\r
+            // NOTE this code works only with one source file\r
+            setBreakpointsRequest.arguments.source.path = ControlInfo.SourceFilesPath;\r
+            setBreakpointsRequest.arguments.lines.AddRange(BreakpointLines);\r
+            setBreakpointsRequest.arguments.breakpoints.AddRange(BreakpointList);\r
+            setBreakpointsRequest.arguments.sourceModified = false;\r
+            Assert.True(VSCodeDebugger.Request(setBreakpointsRequest).Success,\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void SetFuncBreakpoints(string caller_trace)\r
+        {\r
+            SetFunctionBreakpointsRequest setFunctionBreakpointsRequest = new SetFunctionBreakpointsRequest();\r
+            setFunctionBreakpointsRequest.arguments.breakpoints.AddRange(FuncBreakpointList);\r
+            Assert.True(VSCodeDebugger.Request(setFunctionBreakpointsRequest).Success, @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void WasBreakpointHit(string caller_trace, string bpName)\r
+        {\r
+            Func<string, bool> filter = (resJSON) => {\r
+                if (VSCodeDebugger.isResponseContainProperty(resJSON, "event", "stopped")\r
+                    && VSCodeDebugger.isResponseContainProperty(resJSON, "reason", "breakpoint")) {\r
+                    threadId = Convert.ToInt32(VSCodeDebugger.GetResponsePropertyValue(resJSON, "threadId"));\r
+                    return true;\r
+                }\r
+                return false;\r
+            };\r
+\r
+            Assert.True(VSCodeDebugger.IsEventReceived(filter), @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+\r
+            StackTraceRequest stackTraceRequest = new StackTraceRequest();\r
+            stackTraceRequest.arguments.threadId = threadId;\r
+            stackTraceRequest.arguments.startFrame = 0;\r
+            stackTraceRequest.arguments.levels = 20;\r
+            var ret = VSCodeDebugger.Request(stackTraceRequest);\r
+            Assert.True(ret.Success, @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+\r
+            Breakpoint breakpoint = ControlInfo.Breakpoints[bpName];\r
+            Assert.Equal(BreakpointType.Line, breakpoint.Type, @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+            var lbp = (LineBreakpoint)breakpoint;\r
+\r
+            StackTraceResponse stackTraceResponse =\r
+                JsonConvert.DeserializeObject<StackTraceResponse>(ret.ResponseStr);\r
+\r
+            if (stackTraceResponse.body.stackFrames[0].line == lbp.NumLine\r
+                && stackTraceResponse.body.stackFrames[0].source.name == lbp.FileName\r
+                // NOTE this code works only with one source file\r
+                && stackTraceResponse.body.stackFrames[0].source.path == ControlInfo.SourceFilesPath)\r
+                return;\r
+\r
+            throw new ResultNotSuccessException(@"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public void Continue(string caller_trace)\r
+        {\r
+            ContinueRequest continueRequest = new ContinueRequest();\r
+            continueRequest.arguments.threadId = threadId;\r
+            Assert.True(VSCodeDebugger.Request(continueRequest).Success,\r
+                        @"__FILE__:__LINE__"+"\n"+caller_trace);\r
+        }\r
+\r
+        public Context(ControlInfo controlInfo, NetcoreDbgTestCore.DebuggerClient debuggerClient)\r
+        {\r
+            ControlInfo = controlInfo;\r
+            VSCodeDebugger = new VSCodeDebugger(debuggerClient);\r
+        }\r
+\r
+        ControlInfo ControlInfo;\r
+        VSCodeDebugger VSCodeDebugger;\r
+        int threadId = -1;\r
+        string BreakpointSourceName;\r
+        List<SourceBreakpoint> BreakpointList = new List<SourceBreakpoint>();\r
+        List<int> BreakpointLines = new List<int>();\r
+        List<FunctionBreakpoint> FuncBreakpointList = new List<FunctionBreakpoint>();\r
+    }\r
+}\r
+\r
+namespace VSCodeTestBreakpointWithoutStop\r
+{\r
+    class Program\r
+    {\r
+        static void testfunc()\r
+        {                                                                           Label.Breakpoint("bp_func");\r
+            Console.WriteLine("A breakpoint is set on this testfunc");\r
+        }\r
+\r
+        static void Main(string[] args)\r
+        {\r
+            // first checkpoint (initialization) must provide "init" as id\r
+            Label.Checkpoint("init", "bp_test", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.PrepareStart(@"__FILE__:__LINE__");\r
+                Context.PrepareEnd(@"__FILE__:__LINE__");\r
+                Context.WasEntryPointHit(@"__FILE__:__LINE__");\r
+                Context.Continue(@"__FILE__:__LINE__");\r
+\r
+                System.Threading.Thread.Sleep(5000);\r
+\r
+                Context.AddBreakpoint(@"__FILE__:__LINE__", "bp");\r
+                Context.SetBreakpoints(@"__FILE__:__LINE__");\r
+                Context.AddFuncBreakpoint("testfunc");\r
+                Context.SetFuncBreakpoints(@"__FILE__:__LINE__");\r
+            });\r
+\r
+            System.Threading.Thread.Sleep(15000);\r
+\r
+            Console.WriteLine("A breakpoint \"bp\" is set on this line");           Label.Breakpoint("bp");\r
+\r
+            Label.Checkpoint("bp_test", "bp_test2", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.WasBreakpointHit(@"__FILE__:__LINE__", "bp");\r
+                Context.Continue(@"__FILE__:__LINE__");\r
+            });\r
+\r
+            testfunc();\r
+\r
+            Label.Checkpoint("bp_test2", "finish", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.WasBreakpointHit(@"__FILE__:__LINE__", "bp_func");\r
+                Context.Continue(@"__FILE__:__LINE__");\r
+            });\r
+\r
+            Label.Checkpoint("finish", "", (Object context) => {\r
+                Context Context = (Context)context;\r
+                Context.WasExit(@"__FILE__:__LINE__");\r
+                Context.DebuggerExit(@"__FILE__:__LINE__");\r
+            });\r
+        }\r
+    }\r
+}\r
diff --git a/test-suite/VSCodeTestBreakpointWithoutStop/VSCodeTestBreakpointWithoutStop.csproj b/test-suite/VSCodeTestBreakpointWithoutStop/VSCodeTestBreakpointWithoutStop.csproj
new file mode 100644 (file)
index 0000000..2512674
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">\r
+\r
+  <ItemGroup>\r
+    <ProjectReference Include="..\NetcoreDbgTest\NetcoreDbgTest.csproj" />\r
+  </ItemGroup>\r
+\r
+  <PropertyGroup>\r
+    <OutputType>Exe</OutputType>\r
+    <TargetFramework>netcoreapp3.1</TargetFramework>\r
+  </PropertyGroup>\r
+\r
+</Project>\r
index 2e7989190cf686ade246c838a485f2ad35033c00..b03e3ce77033c7746b9fd8cf4e80c4dce2a51218 100644 (file)
@@ -32,6 +32,7 @@ $ALL_TEST_NAMES = @(
     "MITestAsyncLambdaEvaluate"
     "MITestGeneric"
     "MITestEvalArraysIndexers"
+    "MITestBreakpointWithoutStop"
     "VSCodeExampleTest"
     "VSCodeTestBreakpoint"
     "VSCodeTestFuncBreak"
@@ -59,6 +60,7 @@ $ALL_TEST_NAMES = @(
     "VSCodeTestAsyncLambdaEvaluate"
     "VSCodeTestGeneric"
     "VSCodeTestEvalArraysIndexers"
+    "VSCodeTestBreakpointWithoutStop"
 )
 
 # Skipped tests:
index ab4e65d7d111acbe7156ab392661bd25b7c3e5b3..9e1951327b5e35f9c5072c98f52c23ed716cc6fa 100755 (executable)
@@ -46,6 +46,7 @@ ALL_TEST_NAMES=(
     "MITestAsyncLambdaEvaluate"
     "MITestGeneric"
     "MITestEvalArraysIndexers"
+    "MITestBreakpointWithoutStop"
     "VSCodeExampleTest"
     "VSCodeTestBreakpoint"
     "VSCodeTestFuncBreak"
@@ -73,6 +74,7 @@ ALL_TEST_NAMES=(
     "VSCodeTestAsyncLambdaEvaluate"
     "VSCodeTestGeneric"
     "VSCodeTestEvalArraysIndexers"
+    "VSCodeTestBreakpointWithoutStop"
 )
 
 # Skipped tests:
index 06136a9b31573d1a21a02409fe0082cc2a8d0947..5b95a523ee67d27279d607045d59bfe65acb71cd 100644 (file)
@@ -31,6 +31,7 @@ $ALL_TEST_NAMES = @(
     "MITestAsyncLambdaEvaluate"
     "MITestGeneric"
     "MITestEvalArraysIndexers"
+    "MITestBreakpointWithoutStop"
     "VSCodeExampleTest"
     "VSCodeTestBreakpoint"
     "VSCodeTestFuncBreak"
@@ -55,6 +56,7 @@ $ALL_TEST_NAMES = @(
     "VSCodeTestAsyncLambdaEvaluate"
     "VSCodeTestGeneric"
     "VSCodeTestEvalArraysIndexers"
+    "VSCodeTestBreakpointWithoutStop"
 )
 
 # Skipped tests:
index 62567bd648910c8efbe3d291a30b80882022af6d..702fb837fc91c1d89e30d53de0fecee69175974d 100755 (executable)
@@ -68,6 +68,7 @@ ALL_TEST_NAMES=(
     "MITestHotReloadUpdate"
     "MITestGeneric"
     "MITestEvalArraysIndexers"
+    "MITestBreakpointWithoutStop"
     "VSCodeExampleTest"
     "VSCodeTestBreakpoint"
     "VSCodeTestFuncBreak"
@@ -92,6 +93,7 @@ ALL_TEST_NAMES=(
     "VSCodeTestAsyncLambdaEvaluate"
     "VSCodeTestGeneric"
     "VSCodeTestEvalArraysIndexers"
+    "VSCodeTestBreakpointWithoutStop"
 )
 
 # Skipped tests:
index cd8a197ad91831a54b87864a8df9a781aeb17f3e..940875cc4fcce15797013298757d920f84397270 100644 (file)
@@ -118,10 +118,13 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestGeneric", "MITestGeneric\MITestGeneric.csproj", "{E87EB94D-BB5B-41AB-95C2-0A2DBD9B10D0}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestGeneric", "VSCodeTestGeneric\VSCodeTestGeneric.csproj", "{9CB5834C-7C6F-4508-BECB-BA68C916F9B9}"
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestEvalArraysIndexers", "VSCodeTestEvalArraysIndexers\VSCodeTestEvalArraysIndexers.csproj", "{D11414BF-248B-48B7-928B-DCC30D1C843C}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestEvalArraysIndexers", "MITestEvalArraysIndexers\MITestEvalArraysIndexers.csproj", "{BC47D69D-7792-430B-AFEB-051382EA2FD6}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MITestBreakpointWithoutStop", "MITestBreakpointWithoutStop\MITestBreakpointWithoutStop.csproj", "{FC77E25B-B7D0-4E25-8157-BE586DDF23C9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSCodeTestBreakpointWithoutStop", "VSCodeTestBreakpointWithoutStop\VSCodeTestBreakpointWithoutStop.csproj", "{B46CCE8C-49FA-403C-BC5B-1817CAD09130}"
+EndProject
 Global
        GlobalSection(SolutionConfigurationPlatforms) = preSolution
                Debug|Any CPU = Debug|Any CPU
@@ -855,5 +858,29 @@ Global
                {BC47D69D-7792-430B-AFEB-051382EA2FD6}.Release|x64.Build.0 = Release|Any CPU
                {BC47D69D-7792-430B-AFEB-051382EA2FD6}.Release|x86.ActiveCfg = Release|Any CPU
                {BC47D69D-7792-430B-AFEB-051382EA2FD6}.Release|x86.Build.0 = Release|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Debug|x64.Build.0 = Debug|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Debug|x86.Build.0 = Debug|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Release|Any CPU.Build.0 = Release|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Release|x64.ActiveCfg = Release|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Release|x64.Build.0 = Release|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Release|x86.ActiveCfg = Release|Any CPU
+               {FC77E25B-B7D0-4E25-8157-BE586DDF23C9}.Release|x86.Build.0 = Release|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Debug|x64.Build.0 = Debug|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Debug|x86.Build.0 = Debug|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Release|Any CPU.Build.0 = Release|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Release|x64.ActiveCfg = Release|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Release|x64.Build.0 = Release|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Release|x86.ActiveCfg = Release|Any CPU
+               {B46CCE8C-49FA-403C-BC5B-1817CAD09130}.Release|x86.Build.0 = Release|Any CPU
        EndGlobalSection
 EndGlobal