Thanks for pointing out how to get the old behaviour back. Though given it 
is deprecated, I would like to better understand why this happens after all.

Our use case is simple: We have instances of an object called TextDocument 
that are expensive in terms of memory. We have instances of an object 
called DocumentData that holds a weak reference to TextDocument. This weak 
reference was obtained by calling weak(textDocument) from the node-weak 
library. The return value is actually a proxy to the real TextDocument 
instance. Sine this proxy does not represent a pointer to the real 
TextDocument, we do not directly reference it. 
We keep all instances of DocumentData in a map. We have code that simply 
takes out a TextDocument (through the DocumentData from the Map) and works 
with it. Some of this code might store the TextDocument inside other 
objects and release it after a while. In the end we want to be able to free 
the memory of TextDocument by checking for all references to TextDocument 
being gone. Once we find out hat the weak reference is dead (thus, no real 
reference to it anymore besides the weak reference), we can free its 
resources.

In other words I would say our use case is exactly what weak references in 
other languages are for: We can store a reference to an object in a way 
that we do NOT prevent the GC from collecting this object. Since we can 
find out when the object "is dead", we can do follow up work (e.g. free 
more resources that are associated with the TextDocument).

One thing clearly puzzles me though: We added lots of debug code today and 
we found a reproducible case that caused the FATAL crash in code like this:

let data = this.map["foo"]; // this is the map of document datas
let document = data.document; // this is returning the actual TextDocument 
instance
console.log(document.someProperty); // crash!

 Now, you can see how worried we are that such a simple access could cause 
this crash. This has nothing to do with using the object from the callback 
of SetWeak(). In fact, we noticed that the callback is not even fired in 
this case, we often get the FATAL crash without any callback being fired at 
all.

Our theory is that "something" the node-weak module does causes the 
TextDocument instance to get corrupt. Any property access or function call 
on it causes the FATAL crash. 

Now, would it be possible that this is some kind of race condition with the 
GC? We have not been able to find a reliable reproducible case yet.

Ben

On Tuesday, April 12, 2016 at 9:20:41 PM UTC+2, Ali Sheikh wrote:
>
> Another change you might want to consider is if you really need to 
> resurrect an object after it has become weak.
>
> I recently moved Node.js-core away from the deprecated SetWeak API. With a 
> little bit of cleanup, I was able to avoid all the cases where node core 
> was resurrecting an object in the weak callback. It depends on what you are 
> ultimately doing weak references, but it is worth considering if you really 
> need to resurrect objects.
>
>
> On Tue, Apr 12, 2016 at 11:26 AM, <benjami...@gmail.com <javascript:>> 
> wrote:
>
>> We were using NAN 2.x before with node-weak and node.js 4.x without this 
>> issue so I assume that the V8 update to 46 alters the behaviour of the 
>> callback passed into the SetWeak method. 
>>
>> Can you clarify how I would be able to get the old behaviour back by 
>> changing the node-weak module?
>>
>> On Tuesday, April 12, 2016 at 8:22:25 PM UTC+2, Jochen Eisinger wrote:
>>>
>>> ok, so the update to NAN 2.0 broke the node-weak module. Using the 
>>> kParameter weakness type means that the weak callback will come after the 
>>> object was already GC'd, and it's no longer safe to access the object in 
>>> the callback.
>>>
>>> In fact, the requirement for the callback is that it doesn't invoke any 
>>> function in the VM but resets the persistent handle. If you need to do any 
>>> post-processing, you can register a second-pass callback that will be 
>>> invoked later when it's again safe to call into v8.
>>>
>>> If you require the old behavior of getting a pointer to object before it 
>>> dies, you have to rely on the deprecated SetWeak methods (I guess we should 
>>> consider undeprecating it...)
>>>
>>> On Tue, Apr 12, 2016 at 8:11 PM <benjami...@gmail.com> wrote:
>>>
>>>> Evaluating callback on that stack: 0x5a738dc0 
>>>> {weakref.node!Nan::imp::FunctionCallbackWrapper(const 
>>>> v8::FunctionCallbackInfo<v8::Value> &)}
>>>>
>>>> On Tuesday, April 12, 2016 at 7:48:11 PM UTC+2, Jochen Eisinger wrote:
>>>>
>>>>> What function is "callback" in the HandleApiCallHelper frame pointing 
>>>>> to?
>>>>>
>>>>> On Tue, Apr 12, 2016, 7:36 PM <benjami...@gmail.com> wrote:
>>>>>
>>>>>> I should have mentioned my original bug report against V8: 
>>>>>> https://bugs.chromium.org/p/v8/issues/detail?id=4830
>>>>>>
>>>>>> The stacktrace (with node running in debug mode) would be: 
>>>>>> https://gist.github.com/bpasero/fb5f8a6022b37f7b1a34
>>>>>>
>>>>>> I am sitting in the Visual Studio debugger right at the FAIL call and 
>>>>>> can examine the object. Typing "this" just returns that it is a 
>>>>>> v8::internal::Object with a value of 0x0baffedf {...}
>>>>>>
>>>>>> Btw I am able to run IsOddball() and that returns false.
>>>>>>
>>>>>> On Tuesday, April 12, 2016 at 7:31:23 PM UTC+2, Jochen Eisinger wrote:
>>>>>>
>>>>>>> and the value of "this" when you hit the FATAL()
>>>>>>>
>>>>>>> On Tue, Apr 12, 2016 at 7:33 PM Jochen Eisinger <joc...@chromium.org> 
>>>>>>> wrote:
>>>>>>>
>>>>>> Could you post a stack trace that leads to the FATAL()?
>>>>>>>>
>>>>>>>> On Tue, Apr 12, 2016 at 7:27 PM Ben Noordhuis <in...@bnoordhuis.nl> 
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> On Tue, Apr 12, 2016 at 7:11 PM,  <benjami...@gmail.com> wrote:
>>>>>>>>> > Hi,
>>>>>>>>> >
>>>>>>>>> > we (Microsoft VS Code team) are tracking down a very weird 
>>>>>>>>> native crash in
>>>>>>>>> > our use of node.js (5.10.0, V8 46) that only ever shows up since 
>>>>>>>>> we updated
>>>>>>>>> > from node.js 4.x (V8 45). It seems that changes (around the 
>>>>>>>>> Garbace
>>>>>>>>> > Collector?) in V8 46 have an impact to the crash.
>>>>>>>>> >
>>>>>>>>> > Specifically, we are using the node-weak module
>>>>>>>>> > (https://github.com/TooTallNate/node-weak) to be able to get 
>>>>>>>>> weak references
>>>>>>>>> > onto JavaScript objects. This used to work relatively good in 
>>>>>>>>> node.js 4.x,
>>>>>>>>> > but with node.js 5.x we suddenly get the entire node.js program 
>>>>>>>>> to terminate
>>>>>>>>> > with a fatal crash.
>>>>>>>>> >
>>>>>>>>> > Today we were finally able to track the location of where the 
>>>>>>>>> crash
>>>>>>>>> > originates and it seems to happen when our application simply 
>>>>>>>>> calls into a
>>>>>>>>> > property of the object that is weakly referenced. This call at 
>>>>>>>>> one point
>>>>>>>>> > reaches the following assertion:
>>>>>>>>> >
>>>>>>>>> > void Object::VerifyApiCallResultType() {
>>>>>>>>> > #if DEBUG
>>>>>>>>> >   if (!(IsSmi() || IsString() || IsSymbol() || IsSpecObject() ||
>>>>>>>>> >         IsHeapNumber() || IsSimd128Value() || IsUndefined() || 
>>>>>>>>> IsTrue() ||
>>>>>>>>> >         IsFalse() || IsNull())) {
>>>>>>>>> >     FATAL("API call returned invalid object");
>>>>>>>>> >   }
>>>>>>>>> > #endif  // DEBUG
>>>>>>>>> > }
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > The process terminates from the FATAL call, as none of the 
>>>>>>>>> previous checks
>>>>>>>>> > in this method hold.
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > Now, the interesting question is: How would it be possible to 
>>>>>>>>> have a JS
>>>>>>>>> > object where calling properties on it would fail in such a fatal 
>>>>>>>>> way? It
>>>>>>>>> > seems to us that the object we are calling a property on is a 
>>>>>>>>> pointer to a
>>>>>>>>> > location in memory where no V8 object exists anymore. It almost 
>>>>>>>>> seems that
>>>>>>>>> > the object was garbage collected (or moved to another address?) 
>>>>>>>>> without the
>>>>>>>>> > JS side (or more specifically the node-weak side) getting to 
>>>>>>>>> know.
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > Since this only reproduces with using node-weak, it seems very 
>>>>>>>>> likely that
>>>>>>>>> > there is an issue with either node-weak or NAN. In fact, 
>>>>>>>>> node-weak is
>>>>>>>>> > calling into SetWeak()
>>>>>>>>> > (
>>>>>>>>> https://github.com/TooTallNate/node-weak/blob/master/src/weakref.cc#L174
>>>>>>>>> )
>>>>>>>>> > and relies on the fact that the callback passed in is triggered 
>>>>>>>>> and maybe
>>>>>>>>> > this callback is not triggered anymore in a sync fashion but 
>>>>>>>>> rather async?
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > I would appreciate some pointers if there is something that 
>>>>>>>>> could have
>>>>>>>>> > probably changed in V8 46 that could have an impact on this.
>>>>>>>>>
>>>>>>>>> If you have a simple test case (stress on 'simple'), I'll have a 
>>>>>>>>> look.
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> --
>>>>>>>>> v8-dev mailing list
>>>>>>>>>
>>>>>>>> v8-...@googlegroups.com
>>>>>>>>
>>>>>>>>
>>>>>>>>> http://groups.google.com/group/v8-dev
>>>>>>>>> ---
>>>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>>>> Groups "v8-dev" group.
>>>>>>>>>
>>>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>>>>> send an email to v8-dev+un...@googlegroups.com.
>>>>>>>>
>>>>>>>>
>>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>>
>>>>>>>> -- 
>>>>>> -- 
>>>>>> v8-dev mailing list
>>>>>> v8-...@googlegroups.com
>>>>>> http://groups.google.com/group/v8-dev
>>>>>> --- 
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "v8-dev" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>> send an email to v8-dev+un...@googlegroups.com.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>> -- 
>>>> -- 
>>>> v8-dev mailing list
>>>> v8-...@googlegroups.com
>>>> http://groups.google.com/group/v8-dev
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "v8-dev" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to v8-dev+un...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>> -- 
>> -- 
>> v8-dev mailing list
>> v8-...@googlegroups.com <javascript:>
>> http://groups.google.com/group/v8-dev
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "v8-dev" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to v8-dev+un...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> Ali
>

-- 
-- 
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
--- 
You received this message because you are subscribed to the Google Groups 
"v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to