microsoft / Chakra-Samples

Repository for Chakra JavaScript engine related samples.
MIT License
216 stars 84 forks source link

Access violation exception #4

Closed ghost closed 8 years ago

ghost commented 9 years ago

Hi,

Sorry if it's not the right place to ask but wasn't sure how else to contact about this. Currently working on a UWP C# app that uses JsRT. Got an intermittent issue where a SystemAccessViolationException occurs about reading/writing protected memory when invoking the JsCallFunction method. Any suggestions on how this can happen and how to fix it?

In case it helps, we're using MVVM cross and use the messenger plugin to subscribe for messages on the main thread. When a message is received , then we make a call to the JsCallFunction method. The first argument (which i'm told represents "this"), is an object returned by a javascript function similar to the following

function createFoo(){ return new Foo(); }

Initially I thought it's because we had to pin the object so it doesn't get garbage collected via JsAddRef but doing so or even create a property on the global object to store that instance of the Foo class didn't help either. Would appreciate it if you could provide some guidance on the diagnosing this issue

liminzhu commented 9 years ago

Thanks for sharing :). I work on the JSRT team at Microsoft. Do you think you can share a repro/dump with us so that my team could take a closer look? If you don't want to share it publicly here, feel free to reach me at limzh@microsoft.com.

Limin [MSFT]

liminzhu commented 8 years ago

Issue resolved offline.

SrinivasGourarum commented 8 years ago

Could you please brief on how the issue got resolved. We are facing a similar issue. There is access violation exception/ engine execution exception whenever there is a call on UI thread and succeding calls on the JS thread results in exception.

liminzhu commented 8 years ago

Thanks for asking, and yes of course.

On a high level, most of the AV issues here come from that in the C# app, installed callbacks are not retained and got garbage collected before being invoked. For example, you create a function like this,

//JsNativeFunction callback
private static JavaScriptValue nativeFunction(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData) 
{
    //do something here
}

...

JsCreateFunction(nativeFunction, callbackData, func);

The nativeFunction can be garbage collected. So instead you want to hold on to the delegate like in our sample and write,

//JsNativeFunction callback
private static JavaScriptValue nativeFunction(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData) 
{
    //do something here
}

private static readonly JavaScriptNativeFunction nativeFunctionDelegate = nativeFunction;

...

JsCreateFunction(nativeFunctionDelegate , callbackData, func);

Another trick is that you want to call JsAddRef on JavaScript objects that are not going to be stored somewhere on the stack; otherwise you may hit AV as well.

Given this appears to be a common problem, we will look into improving our documentation.

Thanks, Limin Zhu Chakra, Microsoft