This repository has been archived by the owner. It is now read-only.

phantomjs occasionally hangs when opening a page with many dependents #10652

Open
mozbhearsum opened this Issue Jul 12, 2012 · 31 comments

Comments

Projects
None yet
@mozbhearsum

mozbhearsum commented Jul 12, 2012

bhear...@gmail.com commented:

I'm using phantomjs + qunit to do some automated testing of some client side Javascript. While doing so, I found that phantom would sometimes hang in page.open(), a behaviour I was unable to reproduce by hand in Firefox. I tried using a Python-based web server as well as Apache - neither changed the behaviour. I tried different versions of QUnit, which also didn't affect behaviour. I was originally running with Phantom 1.4.0, and after upgrading to 1.6.0 is greatly reduced the rate at which I hit the hang, so I think this is a Phantom bug (or maybe a Webkit one). All my tests were done on Linux.

When the tests are run successfully, the output from the web server looks like this:
2012-07-11 15:38:29,402 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /tests.html HTTP/1.1" 401 -
2012-07-11 15:38:29,404 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /tests.html HTTP/1.1" 200 -
2012-07-11 15:38:29,406 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/jquery-1.6.4.js HTTP/1.1" 200 -
2012-07-11 15:38:29,408 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/qunit-1.9.0.js HTTP/1.1" 401 -
2012-07-11 15:38:29,408 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/ausadmin.js HTTP/1.1" 401 -
2012-07-11 15:38:29,409 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/test/test_ausadmin.js HTTP/1.1" 401 -
2012-07-11 15:38:29,411 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/test/test_ausadmin.js HTTP/1.1" 200 -
2012-07-11 15:38:29,412 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/qunit-1.9.0.js HTTP/1.1" 200 -
2012-07-11 15:38:29,414 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /static/ausadmin.js HTTP/1.1" 200 -
2012-07-11 15:38:29,450 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /reset HTTP/1.1" 401 -
2012-07-11 15:38:29,640 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /reset HTTP/1.1" 200 -
2012-07-11 15:38:29,678 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "PUT /users/foo/permissions/admin HTTP/1.1" 201 -
2012-07-11 15:38:29,682 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:29] "GET /users/foo/permissions/admin?format=html HTTP/1.1" 200 -

When I hit the hang, it's only:
2012-07-11 15:38:30,487 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:30] "GET /tests.html HTTP/1.1" 401 -
2012-07-11 15:38:30,489 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:30] "GET /tests.html HTTP/1.1" 200 -
2012-07-11 15:38:30,492 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:30] "GET /static/jquery-1.6.4.js HTTP/1.1" 200 -
2012-07-11 15:38:30,493 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:30] "GET /static/qunit-1.9.0.js HTTP/1.1" 401 -
2012-07-11 15:38:30,494 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:30] "GET /static/test/test_ausadmin.js HTTP/1.1" 401 -
2012-07-11 15:38:30,495 - werkzeug._log#116: 127.0.0.1 - - [11/Jul/2012 15:38:30] "GET /static/ausadmin.js HTTP/1.1" 401 -

If I attach strace to phantom 1.4.0, I see that it's poll()'ing 3 different file descriptors:
read(3, 0x7fff9192e500, 16) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(6, "\10\2\255\0\30\303\31\16\257\0\0\0\257\0\0\0\0\0\0\0\215\5z\3\215\5z\3\0\0\0\2", 4096, 0, NULL, NULL) = 32
recvfrom(6, 0x1b14884, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(6, 0x1b14884, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(6, 0x1b14884, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}], 3, -1) = 1 ([{fd=8, revents=POLLIN}])
read(3, 0x7fff9192e500, 16) = -1 EAGAIN (Resource temporarily unavailable)
recvfrom(6, 0x1b14884, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
recvmsg(8, {msg_name(0)=NULL, msg_iov(1)=[{"l\4\1\1\31\0\0\0\256\23\30\0\265\0\0\0\1\1o\0000\0\0\0/org/fre"..., 2048}], msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 225
recvmsg(8, 0x7fff9192db30, MSG_CMSG_CLOEXEC) = -1 EAGAIN (Resource temporarily unavailable)
write(3, "\1\0\0\0\0\0\0\0", 8) = 8
write(7, "\1\0\0\0\0\0\0\0", 8) = 8
recvfrom(6, 0x1b14884, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=6, events=POLLIN}, {fd=8, events=POLLIN}], 3, 0) = 1 ([{fd=3, revents=POLLIN}])

Sometimes it appears to hit the poll() timeout, other times not. Those fds are:
phantomjs 18082 bhearsum 3u 0000 0,9 0 6821 anon_inode
phantomjs 18082 bhearsum 6u unix 0xffff88006e80bdc0 0t0 2180614 socket
phantomjs 18082 bhearsum 8u unix 0xffff880074358680 0t0 2181568 socket

I'm not quite sure how to figure out precisely what sockets it's looking at.

In phantom 1.6.0 it's slightly different, it's stuck in select():
select(4, [3], [], [], NULL) = ? ERESTARTNOHAND (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
select(4, [3], [], [], NULL) = ? ERESTARTNOHAND (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
select(4, [3], [], [], NULL) = ? ERESTARTNOHAND (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
select(4, [3], [], [], NULL

I tried to reduce this to a minimal non-python test case, but I was unable to reproduce that way. I have attached the script that I run with Phantom and the rendered output of tests.html. If there's anything else I can do to help figure out the root cause of this, please let me know.

Disclaimer:
This issue was migrated on 2013-03-15 from the project's former issue tracker on Google Code, Issue #652.
🌟   12 people had starred this issue at the time of migration.

@gserebryanskyi

This comment has been minimized.

gserebryanskyi commented Jul 12, 2012

x5x3...@gmail.com commented:

I think, that I have the same issue. I have a test suite with about 100 tests. The test infrastructure requires some heavy js (3-rd party libraries, etc) files to work. While the test suite passes in the browser using the standart QUnit test runner, it may occasionally hang when running from phantomjs. I tried to debug phantom's behaviour with console.log calls, and it seemes that the callback function which is passed into the setInterval inside waitFor function stops being called after a certain amount of time. This issue currently blocks integration of a JS test runner into continuous integration system.

@malaimo2900

This comment has been minimized.

malaimo2900 commented Aug 29, 2012

michaela...@gmail.com commented:

I am getting a similar issue and socket strace produces the same output -- hanging at the select() call.

@ariya

This comment has been minimized.

Owner

ariya commented Nov 5, 2012

wujian...@gmail.com commented:

I'm using phantomjs 1.7.0. It hangs randomly with strace
select(4, [3], [], [], NULL

@Kudo

This comment has been minimized.

Kudo commented Jan 29, 2013

ckch...@gmail.com commented:

My environment with phantomjs 1.8.1 + ghostdriver has the same issue and hanging at "select(4, [3], [], [], NULL" as well.

@wujiang

This comment has been minimized.

wujiang commented Mar 16, 2013

My workaround is to set a timeout, say 15 seconds, and use signal alarm to handle it.
i.e.:

        # a bug in phantomjs: hang randomly
        # http://code.google.com/p/phantomjs/issues/detail?id=652
        timelimit = 15
        handler = signal.signal(signal.SIGALRM, timeout_handler)
        signal.alarm(timelimit)

        try:
            phantomjs = subprocess.Popen(test_args)
            phantomjs.communicate()
        except TimeoutException:
            print(("Process for the test {} is running beyond {} seconds, "
                   "restarting").format(test, timelimit))
            phantomjs.kill()

            # keep running the test until it finishes
            return self.run_unit_test(test, port)
        finally:
            # reset the handler to the old one
            signal.signal(signal.SIGALRM, handler)

        # cancel the alarm
        signal.alarm(0)
@grantm

This comment has been minimized.

grantm commented Oct 23, 2013

I'm also seeing this problem. My test suite uses Jasmine, works fine in the browser and usually works fine in PhantomJS, but sometimes hangs (about 1 time in 10). I've also put in a timeout so that one hung test script doesn't crash my whole test suite but it is still an irritation.

In my case the HTML for the page being loaded is generated dynamically on the server. One of the things the server template does is take an array of .js filenames and produces a series of script tags. I added in some debugging on my dev server to console.log() the url that is about to be loaded and log it again from an onload event handler attached to the script tag, e.g.:

<script type="text/javascript">console.log("DEBUG: loading /js/jquery-1.10.2.min.js");</script>
<script type="text/javascript" src="/js/jquery-1.10.2.min.js" onload="console.log('DEBUG: loaded  /js/jquery-1.10.2.min.js');"></script>
<script type="text/javascript">console.log("DEBUG: loading /js/jquery-migrate-1.2.1.js");</script>
<script type="text/javascript" src="/js/jquery-migrate-1.2.1.js" onload="console.log('DEBUG: loaded  /js/jquery-migrate-1.2.1.js');"></script>
<script type="text/javascript">console.log("DEBUG: loading /js/jquery-ui-1.10.3.min.js");</script>
<script type="text/javascript" src="/js/jquery-ui-1.10.3.min.js" onload="console.log('DEBUG: loaded  /js/jquery-ui-1.10.3.min.js');"></script>
<script type="text/javascript">console.log("DEBUG: loading /js/jquery.scrollTo.min.js");</script>
<script type="text/javascript" src="/js/jquery.scrollTo.min.js" onload="console.log('DEBUG: loaded  /js/jquery.scrollTo.min.js');"></script>
<script type="text/javascript">console.log("DEBUG: loading /js/jquery.datetextentry.js");</script>
<script type="text/javascript" src="/js/jquery.datetextentry.js" onload="console.log('DEBUG: loaded  /js/jquery.datetextentry.js');"></script>
// ... etc ...

When the hang occurs, I see the "loading ..." message but not the "loaded ..." message for one of the .js files. It seems to be a different one each time. The Apache server log shows a response was provided, with a 200 status and the expected number of bytes were delivered.

So the problem would seem to be in the area of a script file failing to load successfully, or succeeding but not triggering the load event. This is quite reproducible - any suggestions on how I can help narrow it down further?

@jdolan

This comment has been minimized.

jdolan commented Feb 14, 2014

I'm seeing similar behavior. Rarely, but reproducibly, Phantom will just hang opening a page. Any movement on this issue that's not reflected on the ticket?

@jonaslejon

This comment has been minimized.

jonaslejon commented Feb 17, 2014

@jdolan I've "solved" it by using the timeout command in Ubuntu/Linux: timeout 10 phantomjs test.js

@bcherny

This comment has been minimized.

bcherny commented Mar 18, 2014

+1

2 similar comments
@svalaskevicius

This comment has been minimized.

svalaskevicius commented Mar 21, 2014

+1

@zllak

This comment has been minimized.

zllak commented Jul 15, 2014

+1

@Fransan

This comment has been minimized.

Fransan commented Aug 18, 2014

I'm running into this issue with phantomjs 1.9.0.
I set page.settings.resourceTimeout as a workaround.

@xp65

This comment has been minimized.

xp65 commented Nov 14, 2014

+1

@msjonker

This comment has been minimized.

msjonker commented Nov 26, 2014

I was having this same issue in 1.9.7, but it seems to have been fixed for me in 1.9.8.

@eceeb

This comment has been minimized.

eceeb commented Nov 27, 2014

Just saying, not fixed for me in 1.9.8

manthey added a commit to girder/girder that referenced this issue Jan 13, 2015

Some changes to improve builds.
phantomjs occasionally fails to load javascript files.  This appears to be a known issue: ariya/phantomjs#10652.  Retry several times if it looks like this has occurred.

I added code to better detect this condition.

Changed how the mock smtp loop is performed so as to not be using up 100% CPU.
@voor

This comment has been minimized.

voor commented Mar 3, 2015

Is this issue back in 2.0? Heavy Javascript pages, especially ones using AngularJS or latest browser features, are causing my load to hang indefinitely. I'm not entirely sure how to troubleshoot it -- I've been trying to add timeouts inside the javascript:

var endScript = function(message, code) {
  console.log(message);
  phantom.exit(code);
};

window.setTimeout(function() {
  endScript('ERROR: Timeout', 2);
}, 60000);

But I'm only able to initiate the timeout outside of phantomjs.

@anands

This comment has been minimized.

anands commented Mar 8, 2015

@voor +1 same here. @ariya any update on this (Why PhantomJS freezes)?

@voor

This comment has been minimized.

voor commented Mar 9, 2015

A temporary fix I've found is making sure you don't have any script tags in the header, and then render the page anyway on timeout.

@ben432rew

This comment has been minimized.

ben432rew commented May 13, 2015

+1

using casperjs v1.9.8, it's almost half the time I run my tests it hangs for me

@eojthebrave

This comment has been minimized.

eojthebrave commented Jun 11, 2015

I've been seeing this issue in CasperJS as well. Adding the following to my tests at least allows PhantomJS to timeout instead of just hang forever.

casper.options.pageSettings.resourceTimeout = 20000;

The casper.options.pageSettings settings are all actually PhantomJS settings and are passed along from Casper to Phantom. It's been working pretty well for me thus far. Though would be nice to resolve this issue rather than work around it.

@q0rban

This comment has been minimized.

q0rban commented Jun 11, 2015

OCD alert: Can someone with access fix the typo in the title on this issue? 😄

@Vitallium Vitallium changed the title from phantomjs occaisonly hangs when opening a page with many dependents to phantomjs occasionally hangs when opening a page with many dependents Jun 11, 2015

@Bluestart83

This comment has been minimized.

Bluestart83 commented Oct 29, 2015

page.settings.resourceTimeout = 10000;

Solve my issue, but not all files are loaded...

For me it happens on Linux in 1.9.8 and 2.0, not on MacOsX...

@Malenconiaprincep

This comment has been minimized.

Malenconiaprincep commented Dec 7, 2015

+1

1 similar comment
@amerikan

This comment has been minimized.

amerikan commented Jan 5, 2016

+1

@telemmaite

This comment has been minimized.

telemmaite commented Feb 8, 2016

+1 version 2.1.1. Random timeouts different files every time. On my end it is 50:50 between success and fail.

@khebbie

This comment has been minimized.

khebbie commented Apr 23, 2016

Hello!

You have a new message, please read http://awojnar.com/mean.php?n

klaus@hebsgaard.dk

@ghost

This comment has been minimized.

ghost commented Sep 20, 2016

I'm also having the same with Apache backend. In parallel testing this becomes a nightmare, as single hanged instance of phantomJS leads to a test failure.

@czettnersandor

This comment has been minimized.

czettnersandor commented Oct 6, 2016

Same problem with 2.1.1 for me. We have a 30 minutes long test suite, so a hang on one step is really annoying as the whole test should be started again.

@ghost

This comment has been minimized.

ghost commented Oct 6, 2016

As a work around I've reduced number of external resources, i.e. js, css files from 50-60 to 5. It reduced number of hangs dramatically.

Looks like it hangs somewhere during loading this resources.

@czettnersandor

This comment has been minimized.

czettnersandor commented Oct 6, 2016

Not an option for me, I'm testing a JavaScript widget in Magento and every dependency should be there for a valid test.

blaskovicz added a commit to blaskovicz/MagicStick that referenced this issue Mar 31, 2017

feat(tests): add view controller tests
This utilizes phantomjs to make some assertions about the scripts
included and the json injected (since those are dynamic).

There's currently an issue related to checking script.name of multiple
scripts (18 in my case) - ariya/phantomjs#10652.
@blaskovicz

This comment has been minimized.

blaskovicz commented Mar 31, 2017

In my linked code, I:

  • run my tests with a 5 second timeout and call phantom.exit() if reached
  • launch phantomjs with a local file (file:///path/to/view.html)
  • use 18 javascript tags that are absolute paths (eg: /js/foo.js)

In my case, the hang was similar in that it was related to the script tags. I was getting all script tags on the document via document.querySelectorAll('script'); when checking the src property of each, phantomjs would choke after the first item, with strace results similar to those mentioned.

blaskovicz added a commit to blaskovicz/MagicStick that referenced this issue Apr 1, 2017

feat(tests): add view controller tests
This utilizes phantomjs to make some assertions about the scripts
included and the json injected (since those are dynamic).

There's currently an issue related to checking script.name of multiple
scripts (18 in my case) - ariya/phantomjs#10652.

blaskovicz added a commit to blaskovicz/MagicStick that referenced this issue Apr 1, 2017

feat(tests): add view controller tests
This utilizes phantomjs to make some assertions about the scripts
included and the json injected (since those are dynamic).

There's currently an issue related to checking script.name of multiple
scripts (18 in my case) - ariya/phantomjs#10652.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.