diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index b1fdd4a2ff8231..c5192dda84b680 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -655,7 +655,13 @@ static StackWalkAction TAStackCrawlCallBackWorker(CrawlFrame* pCf, StackCrawlCon // we can't use it to directly compare against the EH ranges because we // may be in an cloned finally which has a call as the last instruction. - offs--; +#ifdef TARGET_WASM + // On Wasm, R2R code with virtual ips should not have its ip adjusted + if (!ExecutionManager::IsVirtualIP(GetControlPC(pCf->GetRegisterSet()))) +#endif + { + offs--; + } } if (pData->fWriteToStressLog) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/ControlledExecutionTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/ControlledExecutionTests.cs index 4910bead0b75d9..c3b030783c72cd 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/ControlledExecutionTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/ControlledExecutionTests.cs @@ -10,7 +10,6 @@ namespace System.Runtime.Tests { - [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))] public sealed class ControlledExecutionTests { private volatile bool _readyForCancellation; @@ -54,7 +53,7 @@ void Test() // Tests that an infinite loop may be aborted and that the ThreadAbortException is translated // to an OperationCanceledException. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot), nameof(PlatformDetection.IsMultithreadingSupported))] public void CancelOutsideOfTryCatchFinally() { var cts = new CancellationTokenSource(); @@ -103,7 +102,7 @@ void Test() } // Tests that catch blocks are not aborted. The catch block swallows the ThreadAbortException and throws a different exception. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot), nameof(PlatformDetection.IsMultithreadingSupported))] public void CancelInTryAndThrowFromCatch() { var cts = new CancellationTokenSource(); @@ -131,7 +130,7 @@ void Test() } // Tests that finally blocks are not aborted. The finally block exits normally. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot), nameof(PlatformDetection.IsMultithreadingSupported))] public void CancelInFinallyThatSleeps() { var cts = new CancellationTokenSource(); @@ -160,7 +159,7 @@ void Test() } // Tests that finally blocks are not aborted. The finally block throws an exception. - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot))] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime), nameof(PlatformDetection.IsNotNativeAot), nameof(PlatformDetection.IsMultithreadingSupported))] public void CancelInFinallyThatSleepsAndThrows() { var cts = new CancellationTokenSource();