Selenium: Python/Linux quit() does not terminate PhantomJS process

Created on 11 Jul 2015  路  12Comments  路  Source: SeleniumHQ/selenium

Calling quit() on the Python driver seems to leave the phantomjs process running.

(venv2)kmahan@lemur:~/projects/selenium-test$ python
Python 2.7.9 (default, Apr  2 2015, 15:33:21) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from selenium import webdriver
>>> browser = webdriver.PhantomJS()
>>> browser.quit()
>>> 
(venv2)kmahan@lemur:~/projects/selenium-test$ ps ax | grep phantomjs
17503 pts/18   Sl     0:00 /usr/local/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs --webdriver=36954
17518 pts/18   S+     0:00 grep --color=auto phantomjs

https://github.com/SeleniumHQ/selenium/commit/dbac7447d803a6efd33a031df841fa5f51e70ce5 appears to revert a fix from https://code.google.com/p/selenium/issues/detail?id=5921

Possible solution: Calling self.process.terminate() instead of self.process.kill() seems to terminate the process correctly on Linux and should have the same effect as kill() on Windows.

C-py

Most helpful comment

I just hit this as well. The phantomjs subprocess forks a child to do the heavy lifting, and the parent script cannot know to terminate its forked child process when it is simply SIGKILLed by selenium (see the problematic commit mentioned in the first post).

For now, I'm manually sending a SIGTERM to my driver instance's subprocess:

browser.service.process.send_signal(signal.SIGTERM)
browser.quit()

All 12 comments

Hi,
Did you take a look around Phantom JS Repo Bugs here?

HI @nmondal thanks for the pointer. I guess the issue is that webdriver.quit() doesn't terminate the process, and we should not have to rely on SIGKILL or SIGTERMing the process directly. I can try building phantom on my own machine instead of using the version from npm as one of the comments suggests. Will report back.

I just hit this as well. The phantomjs subprocess forks a child to do the heavy lifting, and the parent script cannot know to terminate its forked child process when it is simply SIGKILLed by selenium (see the problematic commit mentioned in the first post).

For now, I'm manually sending a SIGTERM to my driver instance's subprocess:

browser.service.process.send_signal(signal.SIGTERM)
browser.quit()

Until this is fixed in ghostdriver, wouldn't it make sense to revert https://github.com/SeleniumHQ/selenium/commit/dbac7447d803a6efd33a031df841fa5f51e70ce5 ? @barancev

This works for me as a fix:

browser.service.process.send_signal(signal.SIGTERM)
browser.quit()

@romlok
Thanks a lot, my application is server side and this is a huge problem since every user that request a method that have the driver allocates 15 MB in the memory.

Your method works.

As a temporary solution for Python bindings:

First define the function somewhere, for instance in helpers.

def phantom_js_clean_up():
    """Clean up Phantom JS.

    Kills all phantomjs instances, disregard of their origin.
    """
    processes = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
    out, err = processes.communicate()

    for line in out.splitlines():
        if 'phantomjs' in line:
            pid = int(line.split(None, 1)[0])
            os.kill(pid, signal.SIGKILL)

Then run it in the scope of tearDownClass.

@classmethod
def tearDownClass(cls):
    """Tear down class."""
    try:
        cls.driver.quit()
        phantom_js_clean_up()
    except Exception as err:
        print(err)

Hello, for some time now, I have an error:
self.driver.quit() File "/usr/lib/python2.6/site-packages/selenium/webdriver/phantomjs/webdriver.py", line 76, in quit self.service.stop() File "/usr/lib/python2.6/site-packages/selenium/webdriver/common/service.py", line 149, in stop self.send_remote_shutdown_command() File "/usr/lib/python2.6/site-packages/selenium/webdriver/phantomjs/service.py", line 67, in send_remote_shutdown_command os.close(self._cookie_temp_file_handle) OSError: [Errno 9] Bad file descriptor
Code:
self.driver.service.process.send_signal(signal.SIGTERM) self.driver.quit()

CentOs version centos-release-6-7.el6.centos.12.3.i686

Any ideas?
Thanks

Hi, I still have this problem.
File "/home/zhaoli/.local/lib/python2.7/site-packages/selenium/webdriver/phantomjs/webdriver.py", line 76, in quit self.service.stop() File "/home/zhaoli/.local/lib/python2.7/site-packages/selenium/webdriver/common/service.py", line 149, in stop self.send_remote_shutdown_command() File "/home/zhaoli/.local/lib/python2.7/site-packages/selenium/webdriver/phantomjs/service.py", line 67, in send_remote_shutdown_command os.close(self._cookie_temp_file_handle) OSError: [Errno 9] Bad file descriptor

I call the PhantomJS at every httprequest, they won't cause this problem all the time, and it will still work after a refresh.

ubuntu 14.04, python 2.7

Thanks~

Closing this as phantomjs support is being deprecated in favor of chrome or firefox headless

@lmtierney:

That's what I finally ended up with (headless Firefox/Chrome).

Was this page helpful?
0 / 5 - 0 ratings