Which version of PhantomJS are you using?
1.7.0 (development)
What steps will reproduce the problem?
This script crashes PhantomJS with a segmentation fault:
function closure() { var x; return function(){ x; }; } var f = closure(); f(); require('webpage').create().open('http://www.google.com/', f);
Similar crashes happen with other callbacks (onAlert, onConsoleMessage, onLoadFinished, onLoadStarted, onResourceReceived, onResourceRequested, onUrlChanged) but some callbacks seem fine (onConfirm, onError, onPrompt, onInitialized). Weird that onAlert crashes it but not onConfirm!
Comment #1
Posted on Sep 1, 2012 by Massive HorseCan you give an example of somewhere where it crashes with onAlert? I can't seem to reproduce that.
Comment #2
Posted on Sep 1, 2012 by Massive HorseHere is a stack trace I got out of the original example:
0 0x00007fffb004f3ce in ?? ()
1 0x0000000001d864fa in ?? ()
2 0x000000001638a565 in ?? ()
3 0x000000000000000d in ?? ()
4 0x00000000004d5f2a in translate (c=0x7ffff46d4000 "P\001\367\367\377\177", hash=4294955776, location=@0x7ffff4136b28: 0x7fffaffa6b40)
at ../../JavaScriptCore/runtime/Identifier.cpp:106
5 translate (location=@0x7ffff4136b28: 0x7fffaffa6b40, hashCode=4294955776, key=) at ../../JavaScriptCore/wtf/HashSet.h:108
6 addPassingHashCode, char const*, JSC::IdentifierCStringTranslator> > (this=0x7ffff52e75a0, extra=, key=) at ../../JavaScriptCore/wtf/HashTable.h:740
7 add (value=, this=0x7ffff52e75a0) at ../../JavaScriptCore/wtf/HashSet.h:189
8 JSC::IdentifierTable::add (this=0x7ffff52e75a0, value=0x7ffff46d4000 "P\001\367\367\377\177")
at ../../JavaScriptCore/runtime/Identifier.cpp:55
9 0x00000000004d748a in JSC::Identifier::add (globalData=, c=0x8 ) at ../../JavaScriptCore/runtime/Identifier.cpp:130
10 0x00007fffafc33ed0 in ?? ()
11 0x00007ffff7f6b218 in ?? ()
12 0x000000000051a624 in JSC::Bindings::QtConnectionObject::execute (this=0x293ed70, argv=) at ../../WebCore/bridge/qt/qt_runtime.cpp:1863
13 0x000000000051ad4b in JSC::Bindings::QtConnectionObject::qt_metacall (this=0x293ed70, _c=QMetaObject::InvokeMetaMethod, _id=, _a=0x7fffffffd720)
at ../../WebCore/bridge/qt/qt_runtime.cpp:1807
14 0x0000000001bfa7ce in QMetaObject::activate (sender=0x2908310, m=, local_signal_index=, argv=0x7fffffffd720)
at kernel/qobject.cpp:3563
15 0x0000000000451683 in WebPage::loadFinished (this=, _t1=...) at moc_webpage.cpp:327
16 0x00000000004155d2 in WebPage::finish (this=0x2908310, ok=) at webpage.cpp:513
17 0x000000000045189d in WebPage::qt_static_metacall (_o=0x2908310, _c=, _id=, _a=0x2901ed0) at moc_webpage.cpp:209
18 0x0000000001bfe8de in QObject::event (this=0x2908310, e=) at kernel/qobject.cpp:1192
19 0x0000000001558e34 in notify_helper (e=0x29947b0, receiver=0x2908310, this=0x289dd10) at kernel/qapplication.cpp:4551
20 QApplicationPrivate::notify_helper (this=0x289dd10, receiver=0x2908310, e=0x29947b0) at kernel/qapplication.cpp:4523
21 0x000000000155d690 in QApplication::notify (this=0x7fffffffe0f0, receiver=0x2908310, e=0x29947b0) at kernel/qapplication.cpp:4412
22 0x0000000001be711c in QCoreApplication::notifyInternal (this=0x7fffffffe0f0, receiver=0x2908310, event=0x29947b0) at kernel/qcoreapplication.cpp:915
23 0x0000000001beab17 in sendEvent (event=0x29947b0, receiver=0x2908310) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:231
24 QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x289adb0) at kernel/qcoreapplication.cpp:1536
25 0x0000000001c0f7a0 in QEventDispatcherUNIX::processEvents (this=, flags=...) at kernel/qeventdispatcher_unix.cpp:898
26 0x00000000015ae64a in QEventDispatcherQPA::processEvents (this=0x289a010, flags=...) at kernel/qeventdispatcher_qpa.cpp:246
27 0x0000000001be5ec2 in QEventLoop::processEvents (this=, flags=...) at kernel/qeventloop.cpp:149
28 0x0000000001be611f in QEventLoop::exec (this=0x7fffffffe010, flags=...) at kernel/qeventloop.cpp:200
29 0x0000000001bead72 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1187
30 0x000000000040ce3e in main (argc=2, argv=, envp=0x7fffffffe280) at main.cpp:137
This is really hard to debug without getting rid of the ??s. Also there doesn't seem to be instructions on how to get rid of the -O2 compilation flags which makes debugging incredibly difficult.
From what I can see it seems like its the call to JSC::Identifier::add with a bad string that's causing this, but I don't think I can get any more specific then that.
Comment #3
Posted on Sep 15, 2012 by Quick MonkeyCan you give an example of somewhere where it crashes with onAlert?
function closure() { var x; return function(){ x; }; } var p = require('webpage').create(), f = closure(); f(); p.onAlert = f; p.evaluate(function(){ alert(); });
To round out the list of affected callbacks: server.listen also crashes, page.includeJs does not.
PhantomJS has two different ways of invoking callbacks, and one of them seems crash-prone. Some callbacks, like onAlert, use Qt signals; others, like onConfirm, use direct function calls (see webpage.cpp, webserver.cpp, webpage.js, and webserver.js). The callbacks that crash are the ones that use signals. So changing all callbacks to use direct invocation and seeing what that does would be a good first step.
This bug is kinda hard to trigger, though, and probably not a major cause of PhantomJS crashes. It only occurs if a closure f is an immediate callback (e.g., "p.open(url, f)" crashes, but "p.open(url, function(){ f() })" works fine) and f is also called elsewhere in the script. I ran into this bug by doing "log = closure(); log('hi'); p.onConsoleMessage = log;". Triggering it with onLoadFinished seems unlikely -- few users would write such a script (maybe something like "p.onLoadFinished = loadNextPage; loadNextPage();").
As a workaround, change "p.someCallback = f" to "p.someCallback = function(){ f() }".
Comment #4
Posted on Mar 16, 2013 by Happy HorseClosing. This issue has been moved to GitHub: https://github.com/ariya/phantomjs/issues/10741
Status: Migrated
Labels:
Type-Defect
Priority-Medium