using Jint.Native.Object; using Jint.Runtime.Debugger; #pragma warning disable 618 namespace Jint.Tests.Runtime.Debugger; public class DebugHandlerTests { [Fact] public void AvoidsPauseRecursion() { // While the DebugHandler is in a paused state, it shouldn't relay further OnStep calls to Break/Step. // Such calls would occur e.g. if Step/Break event handlers evaluate accessors. Failing to avoid // reentrance in a multithreaded environment (e.g. using ManualResetEvent(Slim)) would cause // a deadlock. string script = @" var obj = { get name() { 'fail'; return 'Smith'; } }; 'target'; "; var engine = new Engine(options => options.DebugMode().InitialStepMode(StepMode.Into)); bool didPropertyAccess = false; engine.Debugger.Step += (sender, info) => { // We should never reach "fail", because the only way it's executed is from // within this Step handler Assert.False(info.ReachedLiteral("fail")); if (info.ReachedLiteral("target")) { var obj = info.CurrentScopeChain[0].GetBindingValue("obj") as ObjectInstance; var prop = obj.GetOwnProperty("name"); // This is where reentrance would occur: var value = engine.Invoke(prop.Get); didPropertyAccess = true; } return StepMode.Into; }; engine.Execute(script); Assert.True(didPropertyAccess); } }