Closed fededamian closed 4 years ago
I am trying this again without using screen
to see if the issue persists while running the tool directly.
Also, I can confirm that after killing the webscreenshot process, the phantomjs ones are not killed, and I had to manually kill them through:
ps aux | grep phantomjs | grep -v grep | awk '{print $2}' | xargs kill -9
That returned the memory status back to normal.
Hello @fededamian,
From what I understand it might come from a memory leak of phantomjs
? It's not the Python process itself that leaks ?
By the way, which Python precise version are you using ?
Without using screen
the issue persists.
These are the outputs for the versions I am running, sorry I omitted that before:
# uname -a
Linux cloud 4.15.0-66-generic #75-Ubuntu SMP Tue Oct 1 05:24:09 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
# python --version
Python 2.7.15+
# python3 --version
Python 3.6.8
# webscreenshot -h | head -1
webscreenshot.py version 2.5
I don't know if it could be due to a PhantomJS memory leak. What I noticed is that a lot of the system calls made to phantomJS create these processes that, after webscreenshot even finishes, still persist. It may be due to the way the syscall to phantomJS is done on the Python script?
Also, it may be interesting to know if this behaviour is also replicated in other people's setups. Maybe nobody noticed this before because, if you have at least 4 GB
of RAM, that would probably be okay to screenshot more than 10k HTTP servers on a single run even with the increasing rate in the memory I noticed. This could be monitored through htop
by checking if the memory increases consistently during a long webscreenshot execution, and also check if the phantomJS processes remain after the tool finished.
There's 2 termination cases for a phantomjs
instance launched by webscreenshot
:
I see in your htop that Python 2 is used: could you try to install webscreenshot
in a Python 3 environment (pip3 install webscreenshot
) and perform the same test ?
The issue is also present using Python3. This time, I think by luck, the webscreenshot run was able to complete. After being finished, my memory is completly occupied:
# free -h
total used free shared buff/cache available
Mem: 1.9G 1.9G 51M 924K 32M 12M
Swap: 0B 0B 0B
And there are 15 PhantomJS processes left there running unclosed:
# ps aux | grep phantomjs | grep -v grep | wc -l
15
There might be a condition in web screenshot in which the PhantomJS is never finished and is still on background consuming RAM. The more HTTP servers you scan, the more likely this condition may appear.
Below is the output of processes left running taken from ps
. The subdomains that were halted in there can be seen. If you want me to provide you with the full list of HTTP servers I'm testing in a private manner I can.
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://030.localization.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_030.localization.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://pdf.localization.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_pdf.localization.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://perf-ecms-alph.stage.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_perf-ecms-alph.stage.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://refer.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_refer.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://res.localization.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_res.localization.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://resources.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_resources.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://business.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_business.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=https://000.localization.att.com:443 output_file=/root/bb/programs/att/domains/att.com/screenshots/https_000.localization.att.com_443.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=https://010.localization.att.com:443 output_file=/root/bb/programs/att/domains/att.com/screenshots/https_010.localization.att.com_443.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://cd2migration.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_cd2migration.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://clouduser.synaptic.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_clouduser.synaptic.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://cmp.localization.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_cmp.localization.att.com_80.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=https://dnf.localization.att.com:443 output_file=/root/bb/programs/att/domains/att.com/screenshots/https_dnf.localization.att.com_443.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=https://dpt.eia.att.com:443 output_file=/root/bb/programs/att/domains/att.com/screenshots/https_dpt.eia.att.com_443.png width=640 height=360 format=png quality=75
/usr/lib/phantomjs/phantomjs --ignore-ssl-errors=true --ssl-protocol=any --ssl-ciphers=ALL /usr/local/lib/python3.6/dist-packages/webscreenshot/webscreenshot.js url_capture=http://localization.att.com:80 output_file=/root/bb/programs/att/domains/att.com/screenshots/http_localization.att.com_80.png width=640 height=360 format=png quality=75
There are also lots of Xvfb
processes left running, which also consume lots of RAM. Take into account that webscreenshot is not running anymore and all these was left from its execution. After killing all the PhantomJS
and Xvfb
Processes RAM goes back to normal:
Xvfb :121 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.fFWunS/Xauthority
Xvfb :122 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.RFp0iv/Xauthority
Xvfb :123 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.VwJLba/Xauthority
Xvfb :124 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.PO88bG/Xauthority
Xvfb :99 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.qbz30S/Xauthority
Xvfb :133 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.hVsOPf/Xauthority
Xvfb :134 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.vzPbb0/Xauthority
Xvfb :125 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.sI5cRM/Xauthority
Xvfb :126 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.kZu0VP/Xauthority
Xvfb :135 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.AGJvNw/Xauthority
Xvfb :136 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.QGlf4j/Xauthority
Xvfb :137 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.H0WpUy/Xauthority
Xvfb :138 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.vMlzvA/Xauthority
Xvfb :139 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.DMIvhl/Xauthority
Xvfb :140 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.rT3S35/Xauthority
Xvfb :127 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.byckkq/Xauthority
Xvfb :128 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.RXkyiT/Xauthority
Xvfb :100 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.ImyE24/Xauthority
Xvfb :141 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.0G34di/Xauthority
Xvfb :142 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.AwkmeH/Xauthority
Xvfb :101 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.oZgHy8/Xauthority
Xvfb :143 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.fPGPFF/Xauthority
Xvfb :144 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.hmkhvk/Xauthority
Xvfb :102 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Zmmcmh/Xauthority
Xvfb :103 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.KkKW6I/Xauthority
Xvfb :145 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.E9Zx2q/Xauthority
Xvfb :104 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.1VS0Dy/Xauthority
Xvfb :105 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Hjo8yK/Xauthority
Xvfb :106 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.xfbuBW/Xauthority
Xvfb :107 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.H4gEsc/Xauthority
Xvfb :108 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.UZYjWy/Xauthority
Xvfb :109 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.7rVClw/Xauthority
Xvfb :110 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.lr8wa8/Xauthority
Xvfb :146 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.DRh9dF/Xauthority
Xvfb :147 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Va98m8/Xauthority
Xvfb :148 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.tzfmxv/Xauthority
Xvfb :111 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.CnpqNX/Xauthority
Xvfb :112 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.IKCnek/Xauthority
Xvfb :113 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.wGCbj4/Xauthority
Xvfb :114 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.NfoJ64/Xauthority
Xvfb :149 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.IAZWNC/Xauthority
Xvfb :150 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.ejIFCz/Xauthority
Xvfb :151 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.3zSZFM/Xauthority
Xvfb :115 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.8djQ8q/Xauthority
Xvfb :152 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.zZLr4C/Xauthority
Xvfb :116 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.31NKUv/Xauthority
Xvfb :153 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.QT17rT/Xauthority
Xvfb :154 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.DBNasx/Xauthority
Xvfb :155 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.IPUBxj/Xauthority
Xvfb :156 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.w2Y2I8/Xauthority
Xvfb :157 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.3mlLSL/Xauthority
Xvfb :158 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.LxGJMb/Xauthority
Xvfb :159 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.UkWRIT/Xauthority
Xvfb :160 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.ItR9ad/Xauthority
Xvfb :130 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.hXDRM3/Xauthority
Xvfb :161 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.3MuC7y/Xauthority
Xvfb :162 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.C74TUk/Xauthority
Xvfb :163 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.WlYh76/Xauthority
Xvfb :164 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.CjHYmf/Xauthority
Xvfb :165 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.UwyAAi/Xauthority
Xvfb :166 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.7ZbwPs/Xauthority
Xvfb :167 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.yugcya/Xauthority
Xvfb :168 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.cfpE3l/Xauthority
Xvfb :169 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.H6nb23/Xauthority
Xvfb :170 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Mj5jLF/Xauthority
Xvfb :171 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.26rFGc/Xauthority
Xvfb :172 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.fNFpA9/Xauthority
Xvfb :173 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.DfUjyZ/Xauthority
Xvfb :178 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.TQCTje/Xauthority
Xvfb :131 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Qk7JFP/Xauthority
Xvfb :174 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.1FAMmd/Xauthority
Xvfb :175 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.QUd5kj/Xauthority
Xvfb :176 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.vfvurO/Xauthority
Xvfb :177 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.b80QOs/Xauthority
Xvfb :179 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.NPoDg6/Xauthority
Xvfb :180 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Gz0zVQ/Xauthority
Xvfb :181 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.gpK1bu/Xauthority
Xvfb :182 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.Z0ghP8/Xauthority
Xvfb :117 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.wxDEYW/Xauthority
Xvfb :183 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.iwmJ0X/Xauthority
Xvfb :184 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.bygwD3/Xauthority
Xvfb :185 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.GHpwuf/Xauthority
Xvfb :186 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.nJmK2A/Xauthority
Xvfb :187 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.mvuh1c/Xauthority
Xvfb :188 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.ReeHo4/Xauthority
Xvfb :189 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.eNxrDn/Xauthority
Xvfb :190 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.FoLXbR/Xauthority
Xvfb :191 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.1hjI8T/Xauthority
Xvfb :192 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.HVta4t/Xauthority
Xvfb :193 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.gZMOCA/Xauthority
Xvfb :118 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.G9qZWU/Xauthority
Xvfb :194 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.CBkDbp/Xauthority
Xvfb :195 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.y7Zx1v/Xauthority
Xvfb :119 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.GFaoDR/Xauthority
Xvfb :196 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.yd2GXi/Xauthority
Xvfb :197 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.X0KrFY/Xauthority
Xvfb :198 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.ZbUkCs/Xauthority
Xvfb :199 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.UX5Csy/Xauthority
Xvfb :200 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.M4CuIx/Xauthority
Xvfb :201 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.KtdZp5/Xauthority
Xvfb :202 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.R0ICZw/Xauthority
Xvfb :203 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.uKngCc/Xauthority
Xvfb :204 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.bnidIJ/Xauthority
Xvfb :205 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.tvGScP/Xauthority
Xvfb :120 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.gRqsQo/Xauthority
Xvfb :129 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.rtciOs/Xauthority
Xvfb :132 -screen 0 640x480x16 -nolisten tcp -auth /tmp/xvfb-run.30UnU4/Xauthority
So it seems to be a common issue for xvfb-run
:
One solution that I will try will be to SIGKILL (on Linux) the process group:
os.killpg(PGID, signal.SIGKILL)
The other one would be to not call xvfb-run
but directly xvfb
:
https://unix.stackexchange.com/a/311599
Fixed in v2.8. Child processes have been grouped in a session per URL to screenshot, the SIGKILL
signal in case if timeout kills the session, so all descendants.
I let you do some tests and use that command to investigate:
$ ps -ejf | egrep "webscreenshot|Xvfb|STIME|convert"
I have read this resources to patch:
I could have had patched with a less elegant solution
While running
webscreenshot
on a Digital Ocean Ubuntu Box with2 GB
of RAM on a list of approximately 7500 valid HTTP servers, the tool starts working correctly with an overall 250-300 MB of memory compsumtion on the whole OS.As the tool continues working, that memory compsumption increases over time until there isn't any more available to use and the tool starts sending errors. I took a screenshot of
htop
, which I'm attaching, during execution while everything still works okay and I notice docens of phantomjs processes, although I set the tool to run just 1 worker. If I kill all these processes everything goes back to normal.The command used was the following:
That was ran inside a
screen
, although I don't think that would make a difference.The could be an issue in the process of finishing phantomjs processes. It would be great if this could be reviewed.
Thanks in advance,
Htop screenshot: