Quantcast
Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

Commented Issue: [BUG] Crash when calling Interrupt() at bad time [112]

0
0
Hello,

we are having issues with a portion of code that basically provokes an exception in user code called by clearscript, and then calls Interrupt on the V8 engine.

It always crashes. Isn't this scenario supposed to function properly ? (I mean, Interrupt should not crash... ?)

Should I explicitely wait before Interrupting in this case ? (but this would be some sort of workaround?)

Cdlt,
Julien.

btw: reproduced on ClearScript 5.4.6 (Nuget version)

```
[Test]
public virtual void TestScriptTerminateCrash()
{
var ctx = new PropertyBag();
using (var engine = new V8ScriptEngine("CrashScript"))
{
engine.AddHostObject("context", ctx);

var eventW = new ManualResetEventSlim(initialState: false);
var tokenSource = new CancellationTokenSource();

// start notification only
var startEvent = new ManualResetEventSlim(false);

ThreadStart main = () =>
{
try
{

ctx["waitCode"] = new Action(() =>
{
// Waiting in the C# code : a cancel exception is generated here
eventW.Wait(tokenSource.Token);

});
ctx["startEvent"] = startEvent;
ctx["counter"] = 0;
try
{
System.DateTime dtRun = System.DateTime.UtcNow;
engine.Execute("dummyDocument.js", @"
// Start
context.counter = 1;

context.startEvent.Set();

context.counter = 2;

context.waitCode();

context.counter = 3;


");
Assert.Inconclusive();
}
catch (Microsoft.ClearScript.ScriptInterruptedException si)
{
Assert.That(si.Message.Contains("interrupted"));
}
catch (Microsoft.ClearScript.ScriptEngineException segx)
{
if (segx.InnerException is System.Reflection.TargetInvocationException &&
segx.InnerException.InnerException != null)
throw segx.InnerException.InnerException;
Assert.Fail();
}
}
catch (OperationCanceledException)
{
}
catch (Exception)
{
Assert.Fail();
}

};

var t = new Thread(main);
t.Start();
Assert.That(startEvent.Wait(5000));

// Cancel + interrupt
tokenSource.Cancel();
//Thread.Sleep(1000); // won't fail if we interrupt later
engine.Interrupt();

t.Join();

Assert.AreEqual(2, (Int32)ctx["counter"]);
}
}

```

Comments: Thanks for reporting this. The root cause is that script interruption in V8 is an asynchronous process during which the script continues to run but many V8 APIs fail. ClearScript defends against these failures in most cases, but you've found another one. We'll have a fix up shortly. One thing to note is that your `context.waitCode()` script line is guaranteed to raise a managed exception, since your main thread cancels the wait rather than setting the event. This is a particularly problematic scenario; the cancellation exception is raised during script interruption and may therefore end up with empty or invalid properties. Unfortunately that's unavoidable given V8's design.

Viewing all articles
Browse latest Browse all 2297