then wait a few seconds, do nothing else.
On my box it segfaults, does it on yours ?
Jérémy.
Did you wait long enough ?
I just recompiled node.js 0.2.2 from tarball,
this time i had to wait about one minute before it segfaults.
>
> On Sep 24, 1:01 pm, "J�r�my Lal" <holi...@gmail.com> wrote:
>> Hi,
>> please launch node,> new process.binding('evals').Script("a");
>>
>> { Context: [Function]
>> , Script:
>> { [Function]
>> createContext: [Function]
>> , runInContext: [Function]
>> , runInThisContext: [Function]
>> , runInNewContext: [Function]
>> }
>>
>> }
>>
>> then wait a few seconds, do nothing else.
>> On my box it segfaults, does it on yours ?
>>
>> J�r�my.
>
>>> Jérémy.
>>
>
> --
> You received this message because you are subscribed to the Google Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com.
> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/nodejs?hl=en.
>
>
Busy-loops with 0.2.2, segfaults with the bleeding edge. Seems there
is a NULL pointer dereference in
v8::internal::MarkCompactCollector::EmptyMarkingStack(), called
indirectly through V8::IdleNotification() in node.cc.
V8 bug?
Thank you for the report.
--
Vyacheslav Egorov
Debug build of node fails with assertion:
> new process.binding('evals').Script("a");
node_g: ../src/node_object_wrap.h:39: void
node::ObjectWrap::Wrap(v8::Handle<v8::Object>): Assertion
`handle->InternalFieldCount() > 0' failed.
I lack knowledge of node.js internals and design so for now I will
assume that there is now V8 GC bug here, probably just a memory
corruption due to API misuse.
--
Vyacheslav Egorov, Software Engineer, V8 Team.
Google Denmark ApS.
Vyacheslav, with what version of node and on what kind of system are
you testing this? I know what causes the assertion you get, only I
don't get it (the assertion, that is, not "don't get it" in a general
sense).
I am running it on x64 Linux box.
Fishy part: node does not fail when you type:
> S = new process.binding('evals').Script; new S("a");
There might be something wrong with Holder() inside a
node::Script::New callback. I will take a deeper look.
--
Vyacheslav Egorov
Yep, that's the same version I'm testing it with.
> Fishy part: node does not fail when you type:
>
>> S = new process.binding('evals').Script; new S("a");
Not sure if it matters, but:
S = new process.binding('evals').Script; new S("a");
indeed works, while:
S = new process.binding('evals').Script; S("a"); // no new
SIGSEGVs after a couple of seconds. This is the stack trace:
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00000000005728ed in
v8::internal::MarkCompactCollector::EmptyMarkingStack() ()
#2 0x00000000006154f3 in
v8::internal::Top::Iterate(v8::internal::ObjectVisitor*,
v8::internal::ThreadLocalTop*) ()
#3 0x000000000054f8d9 in
v8::internal::Heap::IterateStrongRoots(v8::internal::ObjectVisitor*,
v8::internal::VisitMode) ()
#4 0x00000000005772dc in
v8::internal::MarkCompactCollector::MarkLiveObjects() ()
#5 0x000000000057885e in
v8::internal::MarkCompactCollector::CollectGarbage() ()
#6 0x0000000000552234 in
v8::internal::Heap::MarkCompact(v8::internal::GCTracer*) ()
#7 0x0000000000556320 in
v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector,
v8::internal::GCTracer*, v8::internal::Heap::CollectionPolicy) ()
#8 0x0000000000557de0 in v8::internal::Heap::CollectGarbage(int,
v8::internal::AllocationSpace, v8::internal::Heap::CollectionPolicy)
()
#9 0x0000000000558249 in v8::internal::Heap::CollectAllGarbage(bool,
v8::internal::Heap::CollectionPolicy) ()
#10 0x0000000000558457 in v8::internal::Heap::IdleNotification() ()
#11 0x00000000004bbbe9 in Idle (watcher=0xaaed71, revents=-767443975)
at ../src/node.cc:130
#12 0x00000000004e4eed in ev_invoke_pending () at ../deps/libev/ev.c:1997
#13 0x00000000004e92eb in ev_loop (flags=<value optimized out>) at
../deps/libev/ev.c:2359
#14 0x00000000004bb8f7 in Loop (args=<value optimized out>) at
../src/node.cc:1006
#15 0x0000000000515136 in
v8::internal::Builtin_HandleApiCall(v8::internal::(anonymous
namespace)::BuiltinArguments<(v8::internal::BuiltinExtraArguments)1>)
()
You should use node_g binary instead of node to get asserts.
Ok I see what is going on here:
S = new process.binding('evals').Script("a");
is actually parsed as
S = new (process.binding('evals').Script("a")) ();
which is obviously incorrect call. Node does not properly validate
that invocation callbacks are called from expected contexts with an
expected arguments (e.g. node::Script::New could have checked that it
was called from new operator with args.IsConstructCall() method or
alternatively you can supply signatures to callbacks to perform checks
on receiver).
So this is indeed a binding problem not a V8 bug.
--
Vyacheslav Egorov
Thanks for your analysis, Vyacheslav (and your time, of course). I've
been stepping through the code and come to more or less the same
conclusion. It turns out to be quite pervasive in the code base,
actually. I'll post a patch soon(ish).
Thanks Ben. Committed in 55c65cc .
S = new process.binding('evals').Script("a")
parsed as:
S = new (process.binding('evals')).Script("a")
That is, similar to:
x = new process.binding('evals')
S = x.Script("a")
Since "new" on a function call that returns an object always returns
that object, and process.binding('evals') returns an object,
S = new process.binding('evals').Script("a")
is exactly the same as:
S = process.binding('evals').Script("a")
The correct code would be:
S = new (process.binding('evals').Script)("a")
JavaScript: Not The Prettiest Duck.
In any event, Ben's patch is a very good bit of protection against
clobbering the global object or doing other oddness. It's akin to the
"this not instanceof" trick in JS:
function MyCtor () {
if (!(this instanceof MyCtor)) return new MyCtor()
...
}
--i