From: Mikhail Kurinnoi Date: Fri, 19 Jan 2024 14:20:18 +0000 (+0300) Subject: Fix work with managed code in unmapped addresses. X-Git-Tag: accepted/tizen/unified/20240326.104902~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cdf2bae5ebb81fb0ed80f07ae7142062c8c3dcad;p=sdk%2Ftools%2Fnetcoredbg.git Fix work with managed code in unmapped addresses. * Fix stepping for `using` statement. * Fix stepping for `finally` block. * Fix stack trace for `finally` block. Related to https://github.com/Samsung/netcoredbg/issues/154 --- diff --git a/src/debugger/breakpoint_break.cpp b/src/debugger/breakpoint_break.cpp index 121e39c..00e4de3 100644 --- a/src/debugger/breakpoint_break.cpp +++ b/src/debugger/breakpoint_break.cpp @@ -41,6 +41,9 @@ HRESULT BreakBreakpoint::GetFullyQualifiedIlOffset(ICorDebugThread *pThread, Ful ULONG32 ilOffset; CorDebugMappingResult mappingResult; IfFailRet(pILFrame->GetIP(&ilOffset, &mappingResult)); + if (mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) + return E_FAIL; fullyQualifiedIlOffset.modAddress = modAddress; fullyQualifiedIlOffset.methodToken = methodToken; diff --git a/src/debugger/frames.cpp b/src/debugger/frames.cpp index ca0164d..0f1e4eb 100644 --- a/src/debugger/frames.cpp +++ b/src/debugger/frames.cpp @@ -332,6 +332,16 @@ HRESULT WalkFrames(ICorDebugThread *pThread, WalkFramesCallback cb) return Status; #endif // INTEROP_DEBUGGING + ToRelease pILFrame; + IfFailRet(iCorFrame->QueryInterface(IID_ICorDebugILFrame, (LPVOID*) &pILFrame)); + + ULONG32 nOffset; + CorDebugMappingResult mappingResult; + IfFailRet(pILFrame->GetIP(&nOffset, &mappingResult)); + if (mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) + continue; + IfFailRet(cb(FrameCLRManaged, GetIP(¤tCtx), iCorFrame, nullptr)); continue; } diff --git a/src/debugger/stepper_async.cpp b/src/debugger/stepper_async.cpp index 580f5ce..477425e 100644 --- a/src/debugger/stepper_async.cpp +++ b/src/debugger/stepper_async.cpp @@ -268,6 +268,9 @@ HRESULT AsyncStepper::SetupStep(ICorDebugThread *pThread, IDebugger::StepType st ULONG32 ipOffset; CorDebugMappingResult mappingResult; IfFailRet(pILFrame->GetIP(&ipOffset, &mappingResult)); + if (mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) + return E_FAIL; // If we are at end of async method with await blocks and doing step-in or step-over, // switch to step-out, so whole NotifyDebuggerOfWaitCompletion magic happens. @@ -446,7 +449,9 @@ HRESULT AsyncStepper::ManagedCallbackBreakpoint(ICorDebugThread *pThread) ULONG32 ipOffset; CorDebugMappingResult mappingResult; if (FAILED(pFrame->QueryInterface(IID_ICorDebugILFrame, (LPVOID*) &pILFrame)) || - FAILED(pILFrame->GetIP(&ipOffset, &mappingResult))) + FAILED(pILFrame->GetIP(&ipOffset, &mappingResult)) || + mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) { LOGE("Failed receive current IP offset for async step"); return S_FALSE; diff --git a/src/debugger/steppers.cpp b/src/debugger/steppers.cpp index 6395c8e..832026e 100644 --- a/src/debugger/steppers.cpp +++ b/src/debugger/steppers.cpp @@ -71,11 +71,20 @@ HRESULT Steppers::SetupStep(ICorDebugThread *pThread, IDebugger::StepType stepTy { HRESULT Status; m_filteredPrevStep = false; + m_initialStepType = stepType; ToRelease pProcess; IfFailRet(pThread->GetProcess(&pProcess)); DisableAllSteppers(pProcess); + ToRelease pFrame; + IfFailRet(pThread->GetActiveFrame(&pFrame)); + if (pFrame == nullptr) + return E_FAIL; + + ULONG32 ilOffset; + IfFailRet(m_sharedModules->GetFrameILAndSequencePoint(pFrame, ilOffset, m_StepStartSP)); + IfFailRet(m_asyncStepper->SetupStep(pThread, stepType)); if (Status == S_OK) // S_FALSE = setup simple stepper return S_OK; @@ -175,8 +184,34 @@ HRESULT Steppers::ManagedCallbackStepComplete(ICorDebugThread *pThread, CorDebug bool noUserCodeFound = false; // Must be initialized with `false`, since GetFrameILAndNextUserCodeILOffset call could be failed before delegate call. if (SUCCEEDED(Status = m_sharedModules->GetFrameILAndNextUserCodeILOffset(iCorFrame, ipOffset, ilNextUserCodeOffset, &noUserCodeFound))) { + if (reason == CorDebugStepReason::STEP_NORMAL) + { + if (ipOffset != ilNextUserCodeOffset) + { + // Step completed on some compiler generated (not user) code inside user code (for example, `finally` block related code) + IfFailRet(m_simpleStepper->SetupStep(pThread, m_initialStepType)); + return S_OK; + } + else + { + // Step completed on same location in source as it was started, this happens when some user code block have several + // SequencePoints for same line (for example, `using` related code could mix user/compiler generated code for same line). + ULONG32 ilOffset; + Modules::SequencePoint sp; + IfFailRet(m_sharedModules->GetFrameILAndSequencePoint(iCorFrame, ilOffset, sp)); + if (sp.startLine == m_StepStartSP.startLine && + sp.startColumn == m_StepStartSP.startColumn && + sp.endLine == m_StepStartSP.endLine && + sp.endColumn == m_StepStartSP.endColumn && + sp.document == m_StepStartSP.document) + { + IfFailRet(m_simpleStepper->SetupStep(pThread, m_initialStepType)); + return S_OK; + } + } + } // Current IL offset less than IL offset of next close user code line (for example, step-in into async method) - if (reason == CorDebugStepReason::STEP_CALL && ipOffset < ilNextUserCodeOffset) + else if (reason == CorDebugStepReason::STEP_CALL && ipOffset < ilNextUserCodeOffset) { IfFailRet(m_simpleStepper->SetupStep(pThread, IDebugger::StepType::STEP_OVER)); return S_OK; @@ -190,7 +225,7 @@ HRESULT Steppers::ManagedCallbackStepComplete(ICorDebugThread *pThread, CorDebug } else if (noUserCodeFound) { - IfFailRet(m_simpleStepper->SetupStep(pThread, IDebugger::StepType::STEP_IN)); + IfFailRet(m_simpleStepper->SetupStep(pThread, m_initialStepType)); // In case step-in will return from method and no user code was called in user module, step-in again. m_filteredPrevStep = true; return S_OK; diff --git a/src/debugger/steppers.h b/src/debugger/steppers.h index adc0eef..68d1a9c 100644 --- a/src/debugger/steppers.h +++ b/src/debugger/steppers.h @@ -25,6 +25,7 @@ public: m_simpleStepper(new SimpleStepper(sharedModules)), m_asyncStepper(new AsyncStepper(m_simpleStepper, sharedModules, sharedEvalHelpers)), m_sharedModules(sharedModules), + m_initialStepType(IDebugger::StepType::STEP_OVER), m_justMyCode(true), m_stepFiltering(true), m_filteredPrevStep(false) @@ -54,6 +55,8 @@ private: std::shared_ptr m_simpleStepper; std::unique_ptr m_asyncStepper; std::shared_ptr m_sharedModules; + IDebugger::StepType m_initialStepType; + Modules::SequencePoint m_StepStartSP; bool m_justMyCode; // https://docs.microsoft.com/en-us/visualstudio/debugger/navigating-through-code-with-the-debugger?view=vs-2019#BKMK_Step_into_properties_and_operators_in_managed_code // The debugger steps over properties and operators in managed code by default. In most cases, this provides a better debugging experience. diff --git a/src/metadata/modules.cpp b/src/metadata/modules.cpp index bd8f227..7ec0e2e 100644 --- a/src/metadata/modules.cpp +++ b/src/metadata/modules.cpp @@ -329,6 +329,9 @@ HRESULT Modules::GetFrameILAndSequencePoint( CorDebugMappingResult mappingResult; IfFailRet(pILFrame->GetIP(&ilOffset, &mappingResult)); + if (mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) + return E_FAIL; ToRelease pModule; IfFailRet(pFunc->GetModule(&pModule)); @@ -376,6 +379,9 @@ HRESULT Modules::GetFrameILAndNextUserCodeILOffset( CorDebugMappingResult mappingResult; IfFailRet(pILFrame->GetIP(&ilOffset, &mappingResult)); + if (mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) + return E_FAIL; ToRelease pModule; IfFailRet(pFunc->GetModule(&pModule)); @@ -411,6 +417,9 @@ HRESULT Modules::GetStepRangeFromCurrentIP(ICorDebugThread *pThread, COR_DEBUG_S ULONG32 nOffset; CorDebugMappingResult mappingResult; IfFailRet(pILFrame->GetIP(&nOffset, &mappingResult)); + if (mappingResult == MAPPING_UNMAPPED_ADDRESS || + mappingResult == MAPPING_NO_INFO) + return E_FAIL; CORDB_ADDRESS modAddress; IfFailRet(pModule->GetBaseAddress(&modAddress)); diff --git a/test-suite/MITestNoJMCNoFilterStepping/Program.cs b/test-suite/MITestNoJMCNoFilterStepping/Program.cs index 34bc1f7..127cc9a 100644 --- a/test-suite/MITestNoJMCNoFilterStepping/Program.cs +++ b/test-suite/MITestNoJMCNoFilterStepping/Program.cs @@ -261,6 +261,31 @@ namespace MITestNoJMCNoFilterStepping } } + class TestStepWithCompilerGenCode : IDisposable + { + public void Dispose() + { Label.Breakpoint("test_step_comp_Dispose_1"); + ; Label.Breakpoint("test_step_comp_Dispose_2"); + Label.Breakpoint("test_step_comp_Dispose_3");} + + public static void M() + { Label.Breakpoint("test_step_comp_M_1"); + Label.Breakpoint("test_step_comp_M_2");using (var c = new TestStepWithCompilerGenCode()) + { Label.Breakpoint("test_step_comp_M_3"); + ; Label.Breakpoint("test_step_comp_M_4"); + Label.Breakpoint("test_step_comp_M_5");} + using var c2 = new TestStepWithCompilerGenCode(); Label.Breakpoint("test_step_comp_M_6"); + try + { Label.Breakpoint("test_step_comp_M_7"); + ; Label.Breakpoint("test_step_comp_M_8"); + Label.Breakpoint("test_step_comp_M_9");} + finally + { Label.Breakpoint("test_step_comp_M_10"); + ; Label.Breakpoint("test_step_comp_M_11"); + Label.Breakpoint("test_step_comp_M_12");} + Label.Breakpoint("test_step_comp_M_13");} + } + class Program { static void Main(string[] args) @@ -493,7 +518,7 @@ namespace MITestNoJMCNoFilterStepping C.M3(C.M6(), C.M6()); Label.Breakpoint("test_step_arguments_6"); Console.WriteLine("Test steps for arguments end."); Label.Breakpoint("test_step_arguments_end"); - Label.Checkpoint("test_step_arguments", "finish", (Object context) => { + Label.Checkpoint("test_step_arguments", "test_step_comp", (Object context) => { Context Context = (Context)context; Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_1"); Context.StepOver(@"__FILE__:__LINE__"); @@ -618,6 +643,96 @@ namespace MITestNoJMCNoFilterStepping Context.StepIn(@"__FILE__:__LINE__"); Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_end"); + Context.StepOver(@"__FILE__:__LINE__"); + }); + + // Test step-in/step-over for compiler generated code inside user code. + + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_1"); + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_2"); + Console.WriteLine("Test steps end."); Label.Breakpoint("test_step_comp_end"); + + Label.Checkpoint("test_step_comp", "finish", (Object context) => { + Context Context = (Context)context; + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_end"); Context.StepOut(@"__FILE__:__LINE__"); }); diff --git a/test-suite/MITestStepping/Program.cs b/test-suite/MITestStepping/Program.cs index 67ee7e1..9c20328 100644 --- a/test-suite/MITestStepping/Program.cs +++ b/test-suite/MITestStepping/Program.cs @@ -292,6 +292,31 @@ namespace MITestStepping } } + class TestStepWithCompilerGenCode : IDisposable + { + public void Dispose() + { Label.Breakpoint("test_step_comp_Dispose_1"); + ; Label.Breakpoint("test_step_comp_Dispose_2"); + Label.Breakpoint("test_step_comp_Dispose_3");} + + public static void M() + { Label.Breakpoint("test_step_comp_M_1"); + Label.Breakpoint("test_step_comp_M_2");using (var c = new TestStepWithCompilerGenCode()) + { Label.Breakpoint("test_step_comp_M_3"); + ; Label.Breakpoint("test_step_comp_M_4"); + Label.Breakpoint("test_step_comp_M_5");} + using var c2 = new TestStepWithCompilerGenCode(); Label.Breakpoint("test_step_comp_M_6"); + try + { Label.Breakpoint("test_step_comp_M_7"); + ; Label.Breakpoint("test_step_comp_M_8"); + Label.Breakpoint("test_step_comp_M_9");} + finally + { Label.Breakpoint("test_step_comp_M_10"); + ; Label.Breakpoint("test_step_comp_M_11"); + Label.Breakpoint("test_step_comp_M_12");} + Label.Breakpoint("test_step_comp_M_13");} + } + class Program { static void Main(string[] args) @@ -504,7 +529,7 @@ namespace MITestStepping C.M3(C.M6(), C.M6()); Label.Breakpoint("test_step_arguments_6"); Console.WriteLine("Test steps for arguments end."); Label.Breakpoint("test_step_arguments_end"); - Label.Checkpoint("test_step_arguments", "finish", (Object context) => { + Label.Checkpoint("test_step_arguments", "test_step_comp", (Object context) => { Context Context = (Context)context; Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_1"); Context.StepOver(@"__FILE__:__LINE__"); @@ -597,6 +622,96 @@ namespace MITestStepping Context.StepIn(@"__FILE__:__LINE__"); Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_end"); + Context.StepOver(@"__FILE__:__LINE__"); + }); + + // Test step-in/step-over for compiler generated code inside user code. + + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_1"); + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_2"); + Console.WriteLine("Test steps end."); Label.Breakpoint("test_step_comp_end"); + + Label.Checkpoint("test_step_comp", "finish", (Object context) => { + Context Context = (Context)context; + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_end"); Context.StepOut(@"__FILE__:__LINE__"); }); diff --git a/test-suite/VSCodeTestNoJMCNoFilterStepping/Program.cs b/test-suite/VSCodeTestNoJMCNoFilterStepping/Program.cs index 9c953e9..cf62858 100644 --- a/test-suite/VSCodeTestNoJMCNoFilterStepping/Program.cs +++ b/test-suite/VSCodeTestNoJMCNoFilterStepping/Program.cs @@ -318,6 +318,31 @@ namespace VSCodeTestNoJMCNoFilterStepping } } + class TestStepWithCompilerGenCode : IDisposable + { + public void Dispose() + { Label.Breakpoint("test_step_comp_Dispose_1"); + ; Label.Breakpoint("test_step_comp_Dispose_2"); + Label.Breakpoint("test_step_comp_Dispose_3");} + + public static void M() + { Label.Breakpoint("test_step_comp_M_1"); + Label.Breakpoint("test_step_comp_M_2");using (var c = new TestStepWithCompilerGenCode()) + { Label.Breakpoint("test_step_comp_M_3"); + ; Label.Breakpoint("test_step_comp_M_4"); + Label.Breakpoint("test_step_comp_M_5");} + using var c2 = new TestStepWithCompilerGenCode(); Label.Breakpoint("test_step_comp_M_6"); + try + { Label.Breakpoint("test_step_comp_M_7"); + ; Label.Breakpoint("test_step_comp_M_8"); + Label.Breakpoint("test_step_comp_M_9");} + finally + { Label.Breakpoint("test_step_comp_M_10"); + ; Label.Breakpoint("test_step_comp_M_11"); + Label.Breakpoint("test_step_comp_M_12");} + Label.Breakpoint("test_step_comp_M_13");} + } + class Program { static void Main(string[] args) @@ -551,7 +576,7 @@ namespace VSCodeTestNoJMCNoFilterStepping C.M3(C.M6(), C.M6()); Label.Breakpoint("test_step_arguments_6"); Console.WriteLine("Test steps for arguments end."); Label.Breakpoint("test_step_arguments_end"); - Label.Checkpoint("test_step_arguments", "finish", (Object context) => { + Label.Checkpoint("test_step_arguments", "test_step_comp", (Object context) => { Context Context = (Context)context; Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_1"); Context.StepOver(@"__FILE__:__LINE__"); @@ -676,6 +701,96 @@ namespace VSCodeTestNoJMCNoFilterStepping Context.StepIn(@"__FILE__:__LINE__"); Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_end"); + Context.StepOver(@"__FILE__:__LINE__"); + }); + + // Test step-in/step-over for compiler generated code inside user code. + + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_1"); + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_2"); + Console.WriteLine("Test steps end."); Label.Breakpoint("test_step_comp_end"); + + Label.Checkpoint("test_step_comp", "finish", (Object context) => { + Context Context = (Context)context; + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_end"); Context.StepOut(@"__FILE__:__LINE__"); }); diff --git a/test-suite/VSCodeTestStepping/Program.cs b/test-suite/VSCodeTestStepping/Program.cs index 098cc64..a930954 100644 --- a/test-suite/VSCodeTestStepping/Program.cs +++ b/test-suite/VSCodeTestStepping/Program.cs @@ -303,6 +303,31 @@ namespace VSCodeTestStepping } } + class TestStepWithCompilerGenCode : IDisposable + { + public void Dispose() + { Label.Breakpoint("test_step_comp_Dispose_1"); + ; Label.Breakpoint("test_step_comp_Dispose_2"); + Label.Breakpoint("test_step_comp_Dispose_3");} + + public static void M() + { Label.Breakpoint("test_step_comp_M_1"); + Label.Breakpoint("test_step_comp_M_2");using (var c = new TestStepWithCompilerGenCode()) + { Label.Breakpoint("test_step_comp_M_3"); + ; Label.Breakpoint("test_step_comp_M_4"); + Label.Breakpoint("test_step_comp_M_5");} + using var c2 = new TestStepWithCompilerGenCode(); Label.Breakpoint("test_step_comp_M_6"); + try + { Label.Breakpoint("test_step_comp_M_7"); + ; Label.Breakpoint("test_step_comp_M_8"); + Label.Breakpoint("test_step_comp_M_9");} + finally + { Label.Breakpoint("test_step_comp_M_10"); + ; Label.Breakpoint("test_step_comp_M_11"); + Label.Breakpoint("test_step_comp_M_12");} + Label.Breakpoint("test_step_comp_M_13");} + } + class Program { static void Main(string[] args) @@ -517,7 +542,7 @@ namespace VSCodeTestStepping C.M3(C.M6(), C.M6()); Label.Breakpoint("test_step_arguments_6"); Console.WriteLine("Test steps for arguments end."); Label.Breakpoint("test_step_arguments_end"); - Label.Checkpoint("test_step_arguments", "finish", (Object context) => { + Label.Checkpoint("test_step_arguments", "test_step_comp", (Object context) => { Context Context = (Context)context; Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_1"); Context.StepOver(@"__FILE__:__LINE__"); @@ -610,6 +635,96 @@ namespace VSCodeTestStepping Context.StepIn(@"__FILE__:__LINE__"); Context.WasStep(@"__FILE__:__LINE__", "test_step_arguments_end"); + Context.StepOver(@"__FILE__:__LINE__"); + }); + + // Test step-in/step-over for compiler generated code inside user code. + + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_1"); + TestStepWithCompilerGenCode.M(); Label.Breakpoint("test_step_comp_2"); + Console.WriteLine("Test steps end."); Label.Breakpoint("test_step_comp_end"); + + Label.Checkpoint("test_step_comp", "finish", (Object context) => { + Context Context = (Context)context; + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepOver(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_1"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_4"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_5"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_6"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_7"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_8"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_9"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_10"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_11"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_12"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_1"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_2"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_Dispose_3"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_M_13"); + Context.StepIn(@"__FILE__:__LINE__"); + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_2"); + Context.StepOver(@"__FILE__:__LINE__"); + + Context.WasStep(@"__FILE__:__LINE__", "test_step_comp_end"); Context.StepOut(@"__FILE__:__LINE__"); });