does this segfaults for you ?

27 views
Skip to first unread message

Jérémy Lal

unread,
Sep 24, 2010, 5:01:20 AM9/24/10
to nod...@googlegroups.com
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.

Oleg "Sannis" Efimov

unread,
Sep 24, 2010, 5:14:43 AM9/24/10
to nodejs
No. Node.js v0.2.2 on openSUSE 11.3.

Jérémy Lal

unread,
Sep 24, 2010, 5:36:59 AM9/24/10
to nod...@googlegroups.com, Oleg "Sannis" Efimov
On 24/09/2010 11:14, Oleg "Sannis" Efimov wrote:
> No. Node.js v0.2.2 on openSUSE 11.3.

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.
>

Robert Newson

unread,
Sep 24, 2010, 5:46:39 AM9/24/10
to nod...@googlegroups.com
It didn't segfault here (at least not in the first 10 minutes) but it
did become cpu bound.

>>> 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.
>
>

Oleg "Sannis" Efimov

unread,
Sep 24, 2010, 6:24:14 AM9/24/10
to nodejs
Sorry. I've run this 5 times, so It segfault immediatly or don't
segfaults at any time.

Ben Noordhuis

unread,
Sep 24, 2010, 6:32:59 AM9/24/10
to nod...@googlegroups.com
Ubuntu 10.04.1 LTS (x86_64)

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?

Vyacheslav Egorov

unread,
Sep 24, 2010, 6:56:52 AM9/24/10
to nod...@googlegroups.com
We will look at this immediately.

Thank you for the report.
--
Vyacheslav Egorov

Vyacheslav Egorov

unread,
Sep 24, 2010, 7:34:40 AM9/24/10
to nod...@googlegroups.com
It seems that node has some problems with it's bindings to V8.

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.

Ben Noordhuis

unread,
Sep 24, 2010, 7:48:23 AM9/24/10
to nod...@googlegroups.com
On Fri, Sep 24, 2010 at 13:34, Vyacheslav Egorov <veg...@chromium.org> wrote:
> It seems that node has some problems with it's bindings to V8.
>
> 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, 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).

Vyacheslav Egorov

unread,
Sep 24, 2010, 7:58:19 AM9/24/10
to nod...@googlegroups.com
I cloned git repository so I assume that this is tip of the tree, I
configured it with --debug flag.

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

Ben Noordhuis

unread,
Sep 24, 2010, 8:31:17 AM9/24/10
to nod...@googlegroups.com
On Fri, Sep 24, 2010 at 13:58, Vyacheslav Egorov <veg...@chromium.org> wrote:
> I cloned git repository so I assume that this is tip of the tree, I
> configured it with --debug flag.

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>)
()

Vyacheslav Egorov

unread,
Sep 24, 2010, 9:19:00 AM9/24/10
to nod...@googlegroups.com
> Yep, that's the same version I'm testing it with.

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

Ben Noordhuis

unread,
Sep 24, 2010, 10:59:25 AM9/24/10
to nod...@googlegroups.com
> 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.

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).

Ben Noordhuis

unread,
Sep 24, 2010, 11:07:39 AM9/24/10
to nod...@googlegroups.com
Well, if that wasn't fast I don't know what is.

Ryan, can we have an amen?

0001-New-methods-should-be-invoked-as-constructors-not-re.patch

r...@tinyclouds.org

unread,
Sep 29, 2010, 7:05:01 PM9/29/10
to nod...@googlegroups.com
On Fri, Sep 24, 2010 at 8:07 AM, Ben Noordhuis <in...@bnoordhuis.nl> wrote:
> Well, if that wasn't fast I don't know what is.
>
> Ryan, can we have an amen?

Thanks Ben. Committed in 55c65cc .

Isaac Schlueter

unread,
Sep 29, 2010, 7:16:43 PM9/29/10
to nod...@googlegroups.com
Actually, isn't this:

 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

Vyacheslav Egorov

unread,
Sep 30, 2010, 5:15:42 PM9/30/10
to nod...@googlegroups.com
Isaac you are absolutely right. I've misread the grammar. Sorry for
the confusion.
--
Vyacheslav Egorov
Reply all
Reply to author
Forward
0 new messages