Crash when writing to a property without setter

Nov 21, 2014 at 4:31 PM
Edited Nov 24, 2014 at 10:04 AM
Hello !
I'm using Clearscript 5.4 with default V8.

It crashes when trying to write to a property without setter.. but only if I add another global object first, as illustrated with the test below (the fact that it is a PropertyBag does not seems to be relevant). Otherwise it behaves as expected, throwing an exception.

Any idea of what might be happening here ?
#
# Fatal error in ..\..\src\api.cc, line 2905
# CHECK(!(isolate)->external_caught_exception()) failed
#
Exception de première chance à 0x00000000 dans nunit.exe : 0xC0000005: Violation d'accès à l'emplacement 0x0000000000000000.
Exception non gérée à 0x00000000 dans nunit.exe : 0xC0000005: Violation d'accès à l'emplacement 0x0000000000000000.
        class MissingSetter
        {
            private string _back_title;
            public MissingSetter(string title)
            {
                _back_title = title;
            }
            public string title
            {
                get
                {
                    return _back_title;
                }
            }
        }

        [Test]
        public virtual void Test_InterfaceAndScriptAccess_basic([Values(false, true)] bool withPropertyBag)
        {
            using (var run0 = new V8ScriptEngine())
            {
                if (withPropertyBag)
                    run0.AddHostObject("bag", HostItemFlags.GlobalMembers, new PropertyBag());
                run0.AddHostObject("__other_page", HostItemFlags.GlobalMembers, new MissingSetter("BBB"));
                Assert.AreEqual("BBB", run0.Evaluate("title"));
                Assert.Throws<Microsoft.ClearScript.ScriptEngineException>(delegate
                {
                    run0.Execute("title = 'AAA'");
                });
                Assert.AreEqual("BBB", run0.Evaluate("title"));
            }
        }
I didn't took time to debug the issue, although I can confirm that the ~"property cannot be set" exception is correctly thrown, re-thrown as an hostexception, and then thrown as a scriptexception.. then visual studio logs an access violation, and a buffer overrun alert.. well.. an interesting bug :-)
Coordinator
Nov 24, 2014 at 1:41 PM
Hello Julien,

We cannot reproduce the V8 crash with the test code above. The correct exception is delivered to the caller with or without a second GlobalMembers object added before the MissingSetter instance.

One difference is that we're not using NUnit. Could you try replacing the Assert.Throws() call with a try..catch statement?

Thanks!
Nov 25, 2014 at 4:58 PM
Edited Nov 25, 2014 at 5:14 PM
Same behaviour with the try/catch block. It crashes before the catch statement in my code.

it still crashes in the same place (api.cc, line 2905) -- i.e. OS::Abort() is called from here.

just after the ScriptException was thrown in the V8ContextImpl::SetHostObjectProperty() method
and here is the call stack (which is not so relevant since the "external" exception was caught before)
Image

Same things when compiling in Debug mode (for both the unit tests, V8 and Clearscript).
Coordinator
Nov 25, 2014 at 6:20 PM
Edited Nov 25, 2014 at 7:15 PM
Hi Julien,

We've now reproduced the issue, and we'll post a fix shortly.

You've helped us find some very tricky bugs. Thank you!

EDIT: We couldn't reproduce the crash earlier because it's the result of a failing debug-only assertion in V8. You're using a debug build of V8, right?
Nov 26, 2014 at 8:02 AM
Yes the assert/check is only produced in debug.
I mixed-up my first test somehow, I thought I was using release V8/ClearScript but it was the debug version.
Coordinator
Nov 26, 2014 at 12:33 PM
Fix posted here.