Open AnthonyAkentiev opened 9 years ago
Same issue on clean Windows Server 2012!
wkhtmltopdf.exe "http://www.adaperio.ru/engine.html#/search/%D0%BD030%D1%80%D0%BD98" sample.pdf
Same behaviour with "http://yandex.ru"
I'm experiencing what seems to be a similar issue, although it's very random here. I'm on a fully updated 64 bit Debian 7 using 64 bit wkhtmltopdf 0.12.2.1 from wkhtmltopdf.org. Here's a sample command line:
wkhtmltopdf --enable-javascript --debug-javascript --cookie SESSIONID 94F2B96E6BBE3095E41A038014882342 --window-status waitEvent --orientation Portrait "http://theUrl/theArgs" test.pdf
In many cases wkhtmltopdf simply hangs. Requests stop showing up in the apache access log, and output from wkhtmltopdf just stops. There is no other output indicating why it's stopped.
I've used lsof -n | grep wkhtmltopdf to see if wkhtmltopdf has any open TCP connections at the time of the hang and none show up. I've used strace as well, but I'm still interpreting those results.
As a test, I've loaded the URL in Chrome. I've conducted this test several times, and without exception, the page always loads and window.status is set properly when javascript finishes executing.
Using lsof and strace just isn't going to cut it to debug this. Is there any way for wkhtmltopdf to output more debug/progress info? The equivalent of what is output to Chrome's network tab in the developer console would be great, as there are times in the strace output that it looks like this might even be a DNS lookup that's hanging things up.
Daniel
I've been investigating this problem. I've built a debug build of wkhtmltopdf and kept running it until I encountered the hang. It doesn't take too many tries to replicate this problem. Once I triggered the hang, I attached gdb. Here's the backtrace:
(gdb) bt
#0 0x00007fc2433cb453 in select () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x0000000002093939 in qt_safe_select (nfds=5, fdread=0x4408978, fdwrite=0x4408c10, fdexcept=0x4408ea8, orig_timeout=0x7fff94c8bc50)
at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qcore_unix.cpp:89
#2 0x0000000002095b50 in QEventDispatcherUNIX::select (this=0x43fa290, nfds=5, readfds=0x4408978, writefds=0x4408c10, exceptfds=0x4408ea8, timeout=0x7fff94c8bc50)
at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qeventdispatcher_unix.cpp:649
#3 0x00000000020945cd in QEventDispatcherUNIXPrivate::doSelect (this=0x44087c0, flags=..., timeout=0x7fff94c8bc50)
at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qeventdispatcher_unix.cpp:223
#4 0x0000000002096b25 in QEventDispatcherUNIX::processEvents (this=0x43fa290, flags=...) at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qeventdispatcher_unix.cpp:936
#5 0x0000000002064308 in QCoreApplication::processEvents (flags=...) at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qcoreapplication.cpp:1140
#6 0x000000000042a53a in wkhtmltopdf::ConverterPrivate::convert (this=0x440ad30) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:94
#7 0x000000000042a781 in wkhtmltopdf::Converter::convert (this=0x7fff94c932d0) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:149
#8 0x00000000004510d2 in main (argc=12, argv=0x7fff94c93458) at /home/daniel/wkhtmltopdf/src/pdf/wkhtmltopdf.cc:187
The problem seems to be in /home/daniel/wkhtmltopdf/src/lib/converter.cc:93
while (!convertionDone) {
qApp->processEvents(QEventLoop::WaitForMoreEvents | QEventLoop::AllEvents);
This becomes an infinite loop. To test this, I set a breakpoint just after the loop:
(gdb) b /home/daniel/wkhtmltopdf/src/lib/converter.cc:95
Breakpoint 2 at 0x42a549: file /home/daniel/wkhtmltopdf/src/lib/converter.cc, line 95.
(gdb) c
Continuing.
The breakpoint is never reached.
I've forked this project and will now look at adding some debug output in that event loop in the hopes that it will report something relevant when it gets stuck there. I'll report again once I know more.
Daniel
@DanielCeregatti - Very cool! I hope that you will find the problem soon!
@DanielCeregatti: can you try and see if bgra/wkhtmltopdf@91329c452208f14536a0ade4fa0db86b7a1da210 fixes things for you? I never got feedback on it and it seems you can reproduce the issue.
@DanielCeregatti: can you try the fix-hangs
branch and see if it works for you?
So far so good. I've yet to see it hang when using this branch. I plan to deploying a build of this branch to my production environment soon and I'm hopeful that the problem will no longer manifest itself. Thanks for the quick fix!
I guess I spoke too soon. I really hadn't done any true stress testing and decided I'd run wkhtmltopdf in a shell loop and let it run overnight to be completely sure. I barely made it to iteration number 20 before it hung again:
(gdb) bt
#0 0x00007fd66e38d453 in select () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x0000000002093939 in qt_safe_select (nfds=5, fdread=0x3a078f8, fdwrite=0x3a07b90, fdexcept=0x3a07e28, orig_timeout=0x7fff7b926a40) at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qcore_unix.cpp:89
#2 0x0000000002095b50 in QEventDispatcherUNIX::select (this=0x39f9290, nfds=5, readfds=0x3a078f8, writefds=0x3a07b90, exceptfds=0x3a07e28, timeout=0x7fff7b926a40)
at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qeventdispatcher_unix.cpp:649
#3 0x00000000020945cd in QEventDispatcherUNIXPrivate::doSelect (this=0x3a07740, flags=..., timeout=0x7fff7b926a40) at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qeventdispatcher_unix.cpp:223
#4 0x0000000002096b25 in QEventDispatcherUNIX::processEvents (this=0x39f9290, flags=...) at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qeventdispatcher_unix.cpp:936
#5 0x0000000002064308 in QCoreApplication::processEvents (flags=...) at /home/daniel/wkhtmltopdf/qt/src/corelib/kernel/qcoreapplication.cpp:1140
#6 0x000000000042a530 in wkhtmltopdf::ConverterPrivate::convert (this=0x3a0a100) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:94
#7 0x000000000042a77d in wkhtmltopdf::Converter::convert (this=0x7fff7b92e0c0) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:151
#8 0x0000000000451072 in main (argc=12, argv=0x7fff7b92e248) at /home/daniel/wkhtmltopdf/src/pdf/wkhtmltopdf.cc:187
(gdb) f 6
#6 0x000000000042a530 in wkhtmltopdf::ConverterPrivate::convert (this=0x3a0a100) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:94
warning: Source file is more recent than executable.
94 QCoreApplication::processEvents();
(gdb) l
89
90 bool ConverterPrivate::convert() {
91 convertionDone=false;
92 beginConvert();
93 while (!convertionDone) {
94 QCoreApplication::processEvents();
95 QCoreApplication::sendPostedEvents();
96 }
97 return !error;
98 }
(gdb) b /home/daniel/wkhtmltopdf/src/lib/converter.cc:97
Breakpoint 1 at 0x42a544: file /home/daniel/wkhtmltopdf/src/lib/converter.cc, line 97.
(gdb) c
Continuing.
I let it run for another 10 minutes. The breakpoint is never reached.
Regarding this:
warning: Source file is more recent than executable.
I have a clone of the repo on the machine I use for testing and have it switched to the fix-hang branch but I build on another machine. We're still running Wheezy, and I spun up a Jessie instance just to run the build. I then install the .deb file from the build on the test machine.
I must confess, I haven't used gdb or coded in C/C++ in years, and I'm quite rusty. Is there anything you can suggest for figuring out what is causing this?
Here's some more information when wkhtmltopdf hangs:
$ lsof -n | grep 10551
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
wkhtmltop 10551 daniel cwd DIR 254,33 4096 131073 /home/daniel
wkhtmltop 10551 daniel rtd DIR 254,1 4096 2 /
wkhtmltop 10551 daniel txt REG 254,1 206123457 13977 /usr/local/bin/wkhtmltopdf
wkhtmltop 10551 daniel mem REG 254,1 22928 525115 /lib/x86_64-linux-gnu/libnss_dns-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 47616 525095 /lib/x86_64-linux-gnu/libnss_files-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 80712 525117 /lib/x86_64-linux-gnu/libresolv-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 2048512 524707 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
wkhtmltop 10551 daniel mem REG 254,1 392072 529331 /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
wkhtmltop 10551 daniel mem REG 254,1 14392 527992 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
wkhtmltop 10551 daniel mem REG 254,1 20648 529691 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
wkhtmltop 10551 daniel mem REG 254,1 10896 530228 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
wkhtmltop 10551 daniel mem REG 254,1 129840 530395 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
wkhtmltop 10551 daniel mem REG 254,1 169992 524349 /lib/x86_64-linux-gnu/libexpat.so.1.6.0
wkhtmltop 10551 daniel mem REG 254,1 1599504 525100 /lib/x86_64-linux-gnu/libc-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 89056 524448 /lib/x86_64-linux-gnu/libgcc_s.so.1
wkhtmltop 10551 daniel mem REG 254,1 530736 525093 /lib/x86_64-linux-gnu/libm-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 991600 529428 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
wkhtmltop 10551 daniel mem REG 254,1 131107 525119 /lib/x86_64-linux-gnu/libpthread-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 31744 525118 /lib/x86_64-linux-gnu/librt-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 14768 525110 /lib/x86_64-linux-gnu/libdl-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 92752 524421 /lib/x86_64-linux-gnu/libz.so.1.2.7
wkhtmltop 10551 daniel mem REG 254,1 1289744 528981 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
wkhtmltop 10551 daniel mem REG 254,1 74408 529698 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
wkhtmltop 10551 daniel mem REG 254,1 650808 528743 /usr/lib/x86_64-linux-gnu/libfreetype.so.6.8.1
wkhtmltop 10551 daniel mem REG 254,1 225128 530292 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.5.0
wkhtmltop 10551 daniel mem REG 254,1 38768 528479 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
wkhtmltop 10551 daniel mem REG 254,1 158640 524445 /lib/x86_64-linux-gnu/libpng12.so.0.49.0
wkhtmltop 10551 daniel mem REG 254,1 238848 524304 /usr/lib/x86_64-linux-gnu/libjpeg.so.8.4.0
wkhtmltop 10551 daniel mem REG 254,1 136936 525116 /lib/x86_64-linux-gnu/ld-2.13.so
wkhtmltop 10551 daniel mem REG 254,1 34128 6013 /var/cache/fontconfig/945677eb7aeaf62f1d50efc3fb3ec7d8-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 35304 6008 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 10624 6018 /var/cache/fontconfig/de9486f0b47a4d768a594cb4198cb1c6-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 28448 5999 /var/cache/fontconfig/3f7329c5293ffd510edef78f73874cfd-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 13288 6016 /var/cache/fontconfig/6386b86020ecc1ef9690bb720a13964f-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 5536 5995 /var/cache/fontconfig/099525ddca5eae4f2477b69cf2d7f16d-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 5544 5998 /var/cache/fontconfig/61092ac79d9058a69eda095afa0a78f1-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 5856 5997 /var/cache/fontconfig/a722efc6911bbe16667b1a77497ffd37-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 5776 5996 /var/cache/fontconfig/d63fdd8e0f42559533dd777c334fdfcc-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 33848 14694 /var/cache/fontconfig/e13b20fdb08344e0e664864cc2ede53d-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 115808 6014 /var/cache/fontconfig/44f970ff9b6a3db194ffc7bb3ea380d6-le64.cache-3
wkhtmltop 10551 daniel mem REG 254,1 1534672 524749 /usr/lib/locale/locale-archive
wkhtmltop 10551 daniel mem REG 254,1 26066 525139 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
wkhtmltop 10551 daniel 0u CHR 136,5 0t0 8 /dev/pts/5
wkhtmltop 10551 daniel 1u CHR 136,5 0t0 8 /dev/pts/5
wkhtmltop 10551 daniel 2u CHR 136,5 0t0 8 /dev/pts/5
wkhtmltop 10551 daniel 3r DIR 254,1 20480 278953 /usr/share/bash-completion/completions
wkhtmltop 10551 daniel 4r FIFO 0,8 0t0 5411455 pipe
wkhtmltop 10551 daniel 5w FIFO 0,8 0t0 5411455 pipe
wkhtmltop 10551 daniel 6r FIFO 0,8 0t0 5411458 pipe
wkhtmltop 10551 daniel 7w FIFO 0,8 0t0 5411458 pipe
wkhtmltop 10551 daniel 8r FIFO 0,8 0t0 5410750 pipe
wkhtmltop 10551 daniel 9w FIFO 0,8 0t0 5410750 pipe
wkhtmltop 10551 daniel 10r FIFO 0,8 0t0 5410751 pipe
wkhtmltop 10551 daniel 11w FIFO 0,8 0t0 5410751 pipe
wkhtmltop 10551 10552 daniel cwd DIR 254,33 4096 131073 /home/daniel
wkhtmltop 10551 10552 daniel rtd DIR 254,1 4096 2 /
wkhtmltop 10551 10552 daniel txt REG 254,1 206123457 13977 /usr/local/bin/wkhtmltopdf
wkhtmltop 10551 10552 daniel mem REG 254,1 22928 525115 /lib/x86_64-linux-gnu/libnss_dns-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 47616 525095 /lib/x86_64-linux-gnu/libnss_files-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 47616 525095 /lib/x86_64-linux-gnu/libnss_files-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 80712 525117 /lib/x86_64-linux-gnu/libresolv-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 2048512 524707 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
wkhtmltop 10551 10552 daniel mem REG 254,1 392072 529331 /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
wkhtmltop 10551 10552 daniel mem REG 254,1 14392 527992 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
wkhtmltop 10551 10552 daniel mem REG 254,1 20648 529691 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
wkhtmltop 10551 10552 daniel mem REG 254,1 10896 530228 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
wkhtmltop 10551 10552 daniel mem REG 254,1 129840 530395 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
wkhtmltop 10551 10552 daniel mem REG 254,1 169992 524349 /lib/x86_64-linux-gnu/libexpat.so.1.6.0
wkhtmltop 10551 10552 daniel mem REG 254,1 1599504 525100 /lib/x86_64-linux-gnu/libc-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 89056 524448 /lib/x86_64-linux-gnu/libgcc_s.so.1
wkhtmltop 10551 10552 daniel mem REG 254,1 530736 525093 /lib/x86_64-linux-gnu/libm-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 991600 529428 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
wkhtmltop 10551 10552 daniel mem REG 254,1 131107 525119 /lib/x86_64-linux-gnu/libpthread-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 31744 525118 /lib/x86_64-linux-gnu/librt-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 14768 525110 /lib/x86_64-linux-gnu/libdl-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 92752 524421 /lib/x86_64-linux-gnu/libz.so.1.2.7
wkhtmltop 10551 10552 daniel mem REG 254,1 1289744 528981 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
wkhtmltop 10551 10552 daniel mem REG 254,1 74408 529698 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
wkhtmltop 10551 10552 daniel mem REG 254,1 650808 528743 /usr/lib/x86_64-linux-gnu/libfreetype.so.6.8.1
wkhtmltop 10551 10552 daniel mem REG 254,1 225128 530292 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.5.0
wkhtmltop 10551 10552 daniel mem REG 254,1 38768 528479 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
wkhtmltop 10551 10552 daniel mem REG 254,1 158640 524445 /lib/x86_64-linux-gnu/libpng12.so.0.49.0
wkhtmltop 10551 10552 daniel mem REG 254,1 238848 524304 /usr/lib/x86_64-linux-gnu/libjpeg.so.8.4.0
wkhtmltop 10551 10552 daniel mem REG 254,1 136936 525116 /lib/x86_64-linux-gnu/ld-2.13.so
wkhtmltop 10551 10552 daniel mem REG 254,1 34128 6013 /var/cache/fontconfig/945677eb7aeaf62f1d50efc3fb3ec7d8-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 35304 6008 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 10624 6018 /var/cache/fontconfig/de9486f0b47a4d768a594cb4198cb1c6-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 28448 5999 /var/cache/fontconfig/3f7329c5293ffd510edef78f73874cfd-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 13288 6016 /var/cache/fontconfig/6386b86020ecc1ef9690bb720a13964f-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 5536 5995 /var/cache/fontconfig/099525ddca5eae4f2477b69cf2d7f16d-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 5544 5998 /var/cache/fontconfig/61092ac79d9058a69eda095afa0a78f1-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 5856 5997 /var/cache/fontconfig/a722efc6911bbe16667b1a77497ffd37-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 5776 5996 /var/cache/fontconfig/d63fdd8e0f42559533dd777c334fdfcc-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 33848 14694 /var/cache/fontconfig/e13b20fdb08344e0e664864cc2ede53d-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 115808 6014 /var/cache/fontconfig/44f970ff9b6a3db194ffc7bb3ea380d6-le64.cache-3
wkhtmltop 10551 10552 daniel mem REG 254,1 1534672 524749 /usr/lib/locale/locale-archive
wkhtmltop 10551 10552 daniel mem REG 254,1 26066 525139 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
wkhtmltop 10551 10552 daniel 0u CHR 136,5 0t0 8 /dev/pts/5
wkhtmltop 10551 10552 daniel 1u CHR 136,5 0t0 8 /dev/pts/5
wkhtmltop 10551 10552 daniel 2u CHR 136,5 0t0 8 /dev/pts/5
wkhtmltop 10551 10552 daniel 3r DIR 254,1 20480 278953 /usr/share/bash-completion/completions
wkhtmltop 10551 10552 daniel 4r FIFO 0,8 0t0 5411455 pipe
wkhtmltop 10551 10552 daniel 5w FIFO 0,8 0t0 5411455 pipe
wkhtmltop 10551 10552 daniel 6r FIFO 0,8 0t0 5411458 pipe
wkhtmltop 10551 10552 daniel 7w FIFO 0,8 0t0 5411458 pipe
wkhtmltop 10551 10552 daniel 8r FIFO 0,8 0t0 5410750 pipe
wkhtmltop 10551 10552 daniel 9w FIFO 0,8 0t0 5410750 pipe
wkhtmltop 10551 10552 daniel 10r FIFO 0,8 0t0 5410751 pipe
wkhtmltop 10551 10552 daniel 11w FIFO 0,8 0t0 5410751 pipe
QThread 10551 10553 daniel cwd DIR 254,33 4096 131073 /home/daniel
QThread 10551 10553 daniel rtd DIR 254,1 4096 2 /
QThread 10551 10553 daniel txt REG 254,1 206123457 13977 /usr/local/bin/wkhtmltopdf
QThread 10551 10553 daniel mem REG 254,1 22928 525115 /lib/x86_64-linux-gnu/libnss_dns-2.13.so
QThread 10551 10553 daniel mem REG 254,1 47616 525095 /lib/x86_64-linux-gnu/libnss_files-2.13.so
QThread 10551 10553 daniel mem REG 254,1 80712 525117 /lib/x86_64-linux-gnu/libresolv-2.13.so
QThread 10551 10553 daniel mem REG 254,1 2048512 524707 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
QThread 10551 10553 daniel mem REG 254,1 392072 529331 /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
QThread 10551 10553 daniel mem REG 254,1 14392 527992 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
QThread 10551 10553 daniel mem REG 254,1 20648 529691 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
QThread 10551 10553 daniel mem REG 254,1 10896 530228 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
QThread 10551 10553 daniel mem REG 254,1 129840 530395 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
QThread 10551 10553 daniel mem REG 254,1 169992 524349 /lib/x86_64-linux-gnu/libexpat.so.1.6.0
QThread 10551 10553 daniel mem REG 254,1 1599504 525100 /lib/x86_64-linux-gnu/libc-2.13.so
QThread 10551 10553 daniel mem REG 254,1 89056 524448 /lib/x86_64-linux-gnu/libgcc_s.so.1
QThread 10551 10553 daniel mem REG 254,1 530736 525093 /lib/x86_64-linux-gnu/libm-2.13.so
QThread 10551 10553 daniel mem REG 254,1 991600 529428 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
QThread 10551 10553 daniel mem REG 254,1 131107 525119 /lib/x86_64-linux-gnu/libpthread-2.13.so
QThread 10551 10553 daniel mem REG 254,1 31744 525118 /lib/x86_64-linux-gnu/librt-2.13.so
QThread 10551 10553 daniel mem REG 254,1 14768 525110 /lib/x86_64-linux-gnu/libdl-2.13.so
QThread 10551 10553 daniel mem REG 254,1 92752 524421 /lib/x86_64-linux-gnu/libz.so.1.2.7
QThread 10551 10553 daniel mem REG 254,1 1289744 528981 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
QThread 10551 10553 daniel mem REG 254,1 74408 529698 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
QThread 10551 10553 daniel mem REG 254,1 650808 528743 /usr/lib/x86_64-linux-gnu/libfreetype.so.6.8.1
QThread 10551 10553 daniel mem REG 254,1 225128 530292 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.5.0
QThread 10551 10553 daniel mem REG 254,1 38768 528479 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
QThread 10551 10553 daniel mem REG 254,1 158640 524445 /lib/x86_64-linux-gnu/libpng12.so.0.49.0
QThread 10551 10553 daniel mem REG 254,1 238848 524304 /usr/lib/x86_64-linux-gnu/libjpeg.so.8.4.0
QThread 10551 10553 daniel mem REG 254,1 136936 525116 /lib/x86_64-linux-gnu/ld-2.13.so
QThread 10551 10553 daniel mem REG 254,1 34128 6013 /var/cache/fontconfig/945677eb7aeaf62f1d50efc3fb3ec7d8-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 35304 6008 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 10624 6018 /var/cache/fontconfig/de9486f0b47a4d768a594cb4198cb1c6-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 28448 5999 /var/cache/fontconfig/3f7329c5293ffd510edef78f73874cfd-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 13288 6016 /var/cache/fontconfig/6386b86020ecc1ef9690bb720a13964f-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 5536 5995 /var/cache/fontconfig/099525ddca5eae4f2477b69cf2d7f16d-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 5544 5998 /var/cache/fontconfig/61092ac79d9058a69eda095afa0a78f1-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 5856 5997 /var/cache/fontconfig/a722efc6911bbe16667b1a77497ffd37-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 5776 5996 /var/cache/fontconfig/d63fdd8e0f42559533dd777c334fdfcc-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 33848 14694 /var/cache/fontconfig/e13b20fdb08344e0e664864cc2ede53d-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 115808 6014 /var/cache/fontconfig/44f970ff9b6a3db194ffc7bb3ea380d6-le64.cache-3
QThread 10551 10553 daniel mem REG 254,1 1534672 524749 /usr/lib/locale/locale-archive
QThread 10551 10553 daniel mem REG 254,1 26066 525139 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
QThread 10551 10553 daniel 0u CHR 136,5 0t0 8 /dev/pts/5
QThread 10551 10553 daniel 1u CHR 136,5 0t0 8 /dev/pts/5
QThread 10551 10553 daniel 2u CHR 136,5 0t0 8 /dev/pts/5
QThread 10551 10553 daniel 3r DIR 254,1 20480 278953 /usr/share/bash-completion/completions
QThread 10551 10553 daniel 4r FIFO 0,8 0t0 5411455 pipe
QThread 10551 10553 daniel 5w FIFO 0,8 0t0 5411455 pipe
QThread 10551 10553 daniel 6r FIFO 0,8 0t0 5411458 pipe
QThread 10551 10553 daniel 7w FIFO 0,8 0t0 5411458 pipe
QThread 10551 10553 daniel 8r FIFO 0,8 0t0 5410750 pipe
QThread 10551 10553 daniel 9w FIFO 0,8 0t0 5410750 pipe
QThread 10551 10553 daniel 10r FIFO 0,8 0t0 5410751 pipe
QThread 10551 10553 daniel 11w FIFO 0,8 0t0 5410751 pipe
QThread 10551 10554 daniel cwd DIR 254,33 4096 131073 /home/daniel
QThread 10551 10554 daniel rtd DIR 254,1 4096 2 /
QThread 10551 10554 daniel txt REG 254,1 206123457 13977 /usr/local/bin/wkhtmltopdf
QThread 10551 10554 daniel mem REG 254,1 22928 525115 /lib/x86_64-linux-gnu/libnss_dns-2.13.so
QThread 10551 10554 daniel mem REG 254,1 47616 525095 /lib/x86_64-linux-gnu/libnss_files-2.13.so
QThread 10551 10554 daniel mem REG 254,1 80712 525117 /lib/x86_64-linux-gnu/libresolv-2.13.so
QThread 10551 10554 daniel mem REG 254,1 2048512 524707 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
QThread 10551 10554 daniel mem REG 254,1 392072 529331 /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
QThread 10551 10554 daniel mem REG 254,1 14392 527992 /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
QThread 10551 10554 daniel mem REG 254,1 20648 529691 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
QThread 10551 10554 daniel mem REG 254,1 10896 530228 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
QThread 10551 10554 daniel mem REG 254,1 129840 530395 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
QThread 10551 10554 daniel mem REG 254,1 169992 524349 /lib/x86_64-linux-gnu/libexpat.so.1.6.0
QThread 10551 10554 daniel mem REG 254,1 1599504 525100 /lib/x86_64-linux-gnu/libc-2.13.so
QThread 10551 10554 daniel mem REG 254,1 89056 524448 /lib/x86_64-linux-gnu/libgcc_s.so.1
QThread 10551 10554 daniel mem REG 254,1 530736 525093 /lib/x86_64-linux-gnu/libm-2.13.so
QThread 10551 10554 daniel mem REG 254,1 991600 529428 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
QThread 10551 10554 daniel mem REG 254,1 131107 525119 /lib/x86_64-linux-gnu/libpthread-2.13.so
QThread 10551 10554 daniel mem REG 254,1 31744 525118 /lib/x86_64-linux-gnu/librt-2.13.so
QThread 10551 10554 daniel mem REG 254,1 14768 525110 /lib/x86_64-linux-gnu/libdl-2.13.so
QThread 10551 10554 daniel mem REG 254,1 92752 524421 /lib/x86_64-linux-gnu/libz.so.1.2.7
QThread 10551 10554 daniel mem REG 254,1 1289744 528981 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
QThread 10551 10554 daniel mem REG 254,1 74408 529698 /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
QThread 10551 10554 daniel mem REG 254,1 650808 528743 /usr/lib/x86_64-linux-gnu/libfreetype.so.6.8.1
QThread 10551 10554 daniel mem REG 254,1 225128 530292 /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.5.0
QThread 10551 10554 daniel mem REG 254,1 38768 528479 /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
QThread 10551 10554 daniel mem REG 254,1 158640 524445 /lib/x86_64-linux-gnu/libpng12.so.0.49.0
QThread 10551 10554 daniel mem REG 254,1 238848 524304 /usr/lib/x86_64-linux-gnu/libjpeg.so.8.4.0
QThread 10551 10554 daniel mem REG 254,1 136936 525116 /lib/x86_64-linux-gnu/ld-2.13.so
QThread 10551 10554 daniel mem REG 254,1 34128 6013 /var/cache/fontconfig/945677eb7aeaf62f1d50efc3fb3ec7d8-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 35304 6008 /var/cache/fontconfig/6d41288fd70b0be22e8c3a91e032eec0-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 10624 6018 /var/cache/fontconfig/de9486f0b47a4d768a594cb4198cb1c6-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 28448 5999 /var/cache/fontconfig/3f7329c5293ffd510edef78f73874cfd-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 13288 6016 /var/cache/fontconfig/6386b86020ecc1ef9690bb720a13964f-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 5536 5995 /var/cache/fontconfig/099525ddca5eae4f2477b69cf2d7f16d-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 5544 5998 /var/cache/fontconfig/61092ac79d9058a69eda095afa0a78f1-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 5856 5997 /var/cache/fontconfig/a722efc6911bbe16667b1a77497ffd37-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 5776 5996 /var/cache/fontconfig/d63fdd8e0f42559533dd777c334fdfcc-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 33848 14694 /var/cache/fontconfig/e13b20fdb08344e0e664864cc2ede53d-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 115808 6014 /var/cache/fontconfig/44f970ff9b6a3db194ffc7bb3ea380d6-le64.cache-3
QThread 10551 10554 daniel mem REG 254,1 1534672 524749 /usr/lib/locale/locale-archive
QThread 10551 10554 daniel mem REG 254,1 26066 525139 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
QThread 10551 10554 daniel 0u CHR 136,5 0t0 8 /dev/pts/5
QThread 10551 10554 daniel 1u CHR 136,5 0t0 8 /dev/pts/5
QThread 10551 10554 daniel 2u CHR 136,5 0t0 8 /dev/pts/5
QThread 10551 10554 daniel 3r DIR 254,1 20480 278953 /usr/share/bash-completion/completions
QThread 10551 10554 daniel 4r FIFO 0,8 0t0 5411455 pipe
QThread 10551 10554 daniel 5w FIFO 0,8 0t0 5411455 pipe
QThread 10551 10554 daniel 6r FIFO 0,8 0t0 5411458 pipe
QThread 10551 10554 daniel 7w FIFO 0,8 0t0 5411458 pipe
QThread 10551 10554 daniel 8r FIFO 0,8 0t0 5410750 pipe
QThread 10551 10554 daniel 9w FIFO 0,8 0t0 5410750 pipe
QThread 10551 10554 daniel 10r FIFO 0,8 0t0 5410751 pipe
QThread 10551 10554 daniel 11w FIFO 0,8 0t0 5410751 pipe
$ ls -la /proc/10551/fd
total 0
dr-x------ 2 daniel daniel 0 May 20 19:49 .
dr-xr-xr-x 8 daniel daniel 0 May 20 19:47 ..
lrwx------ 1 daniel daniel 64 May 20 19:49 0 -> /dev/pts/5
lrwx------ 1 daniel daniel 64 May 20 19:49 1 -> /dev/pts/5
lrwx------ 1 daniel daniel 64 May 20 19:49 2 -> /dev/pts/5
lr-x------ 1 daniel daniel 64 May 20 19:49 3 -> /usr/share/bash-completion/completions
lr-x------ 1 daniel daniel 64 May 20 19:49 4 -> pipe:[5411455]
l-wx------ 1 daniel daniel 64 May 20 19:49 5 -> pipe:[5411455]
lr-x------ 1 daniel daniel 64 May 20 19:49 6 -> pipe:[5411458]
l-wx------ 1 daniel daniel 64 May 20 19:49 7 -> pipe:[5411458]
lr-x------ 1 daniel daniel 64 May 20 19:49 8 -> pipe:[5410750]
l-wx------ 1 daniel daniel 64 May 20 19:49 9 -> pipe:[5410750]
lr-x------ 1 daniel daniel 64 May 20 19:49 10 -> pipe:[5410751]
l-wx------ 1 daniel daniel 64 May 20 19:49 11 -> pipe:[5410751]
Note there are no open network connections. My tests show that all page assets are delivered by the web server when wkhtmltopdf hangs. The output from an attempt that hangs shows none of my debug output from javascript, so it seems the hang happens after all page assets are downloaded and before javascript starts.
It's also apparent that wkhtmltopdf is threaded. I didn't find the word "thread" anywhere in the src directory, so I'm guessing this is happening implicitly in Qt. Not sure if this is relevant, but thread #4 is always in pthread_cond_wait() when the hang happens, which I suppose could indicate a deadlock:
(gdb) info thread
Id Target Id Frame
4 Thread 0x7fd66d861700 (LWP 7870) "wkhtmltopdf" 0x00007fd66eded344 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/x86_64-linux-gnu/libpthread.so.0
3 Thread 0x7fd66cf50700 (LWP 7871) "QThread" 0x00007fd66e38d453 in select () from /lib/x86_64-linux-gnu/libc.so.6
2 Thread 0x7fd667fff700 (LWP 7872) "QThread" 0x00007fd66e38d453 in select () from /lib/x86_64-linux-gnu/libc.so.6
* 1 Thread 0x7fd6708b5720 (LWP 7869) "wkhtmltopdf" 0x00007fd66e38d453 in select () from /lib/x86_64-linux-gnu/libc.so.6
I'm currently trying to find a public web site that causes the hang. I can't use my site since it requires very specific steps to stage the session which produces the page to be rendered to PDF. The page also contains customer data, so even if I was willing to stage it, I could not expose that for the sake of troubleshooting a bug.
Do you have any ideas - why on Mac OS X it works fine? I am currently running fully updated Mac and wkhtmltopdf never hanged.
I can't help but wonder if the problem is strictly javascript related. If perhaps some file isn't being loaded, and that causes javascript to never run. The fact that I'm using --window-status means that wkhtmltopdf will always wait until that's set, even if it has to wait forever, since there's no option for a global timeout. It makes sense that it would be waiting for that in the while() loop in converter.cc.
Speaking of that while() loop, one bad thing that I've noticed is that there is no delay in that loop. Its thread runs at 100% CPU, even though nothing is really happening. This begs the question: Why doesn't wkhtmltopdf use QApplication::exec()? Every Qt example that I've seen uses it to start event processing. I really feel that running your own loop and calling QApplication::processEvents() is not an intended use of Qt. I've even read on the Qt forums that calling QApplication::processEvents() in a loop is dangerous, in that it can create more events, which can then create an infinite loop. Presumably that's the case when using QApplication::exec() though, but still, I feel that not using exec() is wrong.
Regardless, I really feel that more debugging output is needed from wkhtmltopdf. It really needs to report things like requests made to retrieve page assets and how long they took, when the window.onload event is fired, etc.. It would help in figuring this out.
@DanielCeregatti: the reason QApplication::exec
isn't used because of the libwkhtmltox
bindings. In a command-line application, it is quite easy to have a blocking call to exec()
but not acceptable in a library call to wkhtmltopdf_init
. If that can be solved (possibly via a refactoring of the current codebase) then a local event loop via QEventLoop
can be created to simulate the same blocking behavior without the high CPU usage.
Were you able to diagnose your problem?
I was not. I'm still seeing wkhtmltopdf hang while loading our pages. Given that the loop runs millions of times, and without being able to easily trace through the code to see exactly what it's doing, it became extremely difficult to determine exactly what was causing it to hang. I can tell you this much: The hang always happens before window.onload triggers in the document. My guess is some page asset that never loads. Is there an internal timeout set for the retrieval of page assets? I haven't looked into this, but it seems likely.
The flip side of potentially blocking Qt's event loop by using exec() seems to have been the introduction of an infinite loop, from which the library would certainly also suffer. It seems that either way there's a problem here.
Would it be possible to add a usleep() call inside the loop to keep the CPU load down? Otherwise this is pretty much a runaway thread when no events are processed.
If there is anything else you can suggest, please let me know. We're committed to using wkhtmltopdf, so I'd like to do anything I can to help.
Does removing the --window-status
option stop all the hangs? You can uncomment src/lib/multipageloader.cc:290
and see if it is the reason.
It appears that I'm having a similar issue to Daniel. My thread information matches his when wkhtmltopdf hangs on the loading pages. Interestingly enough, when I render the same webpage the majority of the time it works and occasionally it hangs. So I have disabled javascript and it no longer hangs. For my purposes, I require javascript on the page, but this might help isolate the issue.
Fedora 21, wkhtmltopdf 0.12.2.1
@Indigo: can you post a reproducible test case and command-line parameters? It is hard to fix an issue if you can't reproduce it...
@ashkulz, I have the same issue, here the reproducible example: wkhtmltoimage.exe -f png "http://finance.yahoo.com/q/hp?s=VLDI&a=5&d=5&f=2015&e=1&c=2015&b=1&g=d" "result.png"
As said above, it stops hanging with -n (--disable-javascript) parameter.
@ashkulz Could I send them to you via email?
@ashkulz
I've found some interesting information. First, @DanielCeregatti is correct that it is hanging in
bool ConverterPrivate::convert().
in qcoreapplication.cpp:1510
if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
--data->postEventList.recursion;
return;
}
postEventList.size() always equals zero, which means no events are being posted to its queue, which means
void PdfConverterPrivate::printDocument()
will never be called and therefore convertionDone will never be true. I traced through wkhtmltox and qt and it appeared to be hanging during the http socket communication so I ran wireshark and captured the traffic. I'm confident that it appears to hang when wkhtmltox sends the webserver a reset packet for an unknown reason. This happens after wkhtmltox receives GET request response with 200 OK. I can only assume the socket is then closed and the thread terminates, leaving wkhtmltox waiting for events that will never come?
Example of failure http scenario: SYN SYN,ACK ACK GET ACK FIN,ACK HTTP 200 OK RST
Instead of: SYN, SYN,ACK ACK GET ACK HTTP 200 OK ACK FIN,ACK FIN,ACK ACK
@lndigo: are you able to reproduce it at will?
It is intermittent but I can reproduce it after running on average 30 iterations. In my project I generate HTML and host it on a local webserver and use wkhtmltox to convert it to PDF, therefore I'm able to reproduce the error in a controlled environment.
@ashkulz It seems that the event queue should never be empty and when it is, wkhtmltox ends up in an infinite loop. I'm not sure if QT is emitting an error and wkhtmltox is not subscribed to it or if QT does not emit an error when it resets a socket. Either way, that might handle the scenario to prevent an infinite loop. What about the code below?
do {
QCoreApplication::processEvents();
QCoreApplication::sendPostedEvents();
} while(!convertionDone && QThreadData::current()->postEventList.size() != 0)
Edit: I've done more testing and it always hangs when QT sends a FIN,ACK when the webserver sends an ACK after QT makes a GET request. After QT's FIN,ACK the webserver sends a HTTP response and QT was expecting a FIN,ACK and so it sends a RST. I don't know why QT is sending a FIN,ACK before the HTTP response is delivered.
Edit 2: I rebuilt with debugging enabled for qt network. It appears when qt resets the connection QNativeSocketEnginePrivate::nativeRead encounters an EAGAIN errno and then proceeds to reset the connection. Maybe patch so QT doesn't reset the connection on EAGAIN?
I have suspected that some sort of network issue or failed request was at fault here. The pages that I'm rendering can perform as many as 300 requests in our development environment for the javascript files, css files, image files, as well as XMLHttpRequests for asynchronous data. In production we serve a single combined file for javascript and css files, so the total number of files is substantially smaller there.
Anyhow, I have been able to consistently reproduce the problem by killing the web server that's serving the pages (in my case apache) with SIGKILL while wkhtmltopdf is still getting the page's files. Once killed, wkhtmltopdf will output that it was not able to download the files and hang. I've removed the URL from the following output because this is a business site that is not open to the public, so using the actual URLs would not help troubleshoot the problem. Here's the output:
$ wkhtmltopdf --load-error-handling abort --debug-javascript --cookie SESSIONID 689316CD46A9396C06C23E6D94CA4FE4 --window-status waitEvent --orientation Portrait "URL REDACTED" test.pdf
Loading pages (1/6)
Warning: URL REDACTED/jquery-migrate-1.2.1.js:6 JQMIGRATE: Logging is active
Error: Failed to load URL REDACTED/file1.js, with code: 1002 (sometimes it will work just to ignore this error with --load-media-error-handling ignore)
Error: Failed to load URL REDACTED/file2.js, with code: 1002 (sometimes it will work just to ignore this error with --load-media-error-handling ignore)
... (This list is quite large, so it's truncated)
Warning: undefined:0 ReferenceError: Can't find variable: someVariable
Warning: undefined:0 ReferenceError: Can't find variable: someOtherVariable
[============================================================] 100%
At this point wkhtmltopdf is hung. This is reproducible 100% of the time as long as you catch wkhtmltopdf trying to load the page's files when you SIGKILL the web server. Here's a backtrace:
(gdb) bt
#0 0x00007fe39295b48d in nanosleep () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007fe392985b74 in usleep () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00000000004295b3 in wkhtmltopdf::ConverterPrivate::convert (this=0x4731910) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:97
#3 0x00000000004297fb in wkhtmltopdf::Converter::convert (this=0x7fff8f590400) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:153
#4 0x0000000000450206 in main (argc=15, argv=0x7fff8f590588) at /home/daniel/wkhtmltopdf/src/pdf/wkhtmltopdf.cc:187
(gdb) f 2
#2 0x00000000004295b3 in wkhtmltopdf::ConverterPrivate::convert (this=0x4731910) at /home/daniel/wkhtmltopdf/src/lib/converter.cc:97
warning: Source file is more recent than executable.
97 usleep (100000);
(gdb) l
92 convertionDone=false;
93 beginConvert();
94 while (!convertionDone) {
95 QCoreApplication::processEvents();
96 QCoreApplication::sendPostedEvents();
97 usleep (100000);
98 }
99 return !error;
100 }
101
I'm using the fix-hangs branch with some additional code:
diff --git a/src/lib/converter.cc b/src/lib/converter.cc
index 6dba2ff..ddee751 100644
--- a/src/lib/converter.cc
+++ b/src/lib/converter.cc
@@ -23,6 +23,7 @@
#include "multipageloader.hh"
#include <QWebFrame>
#include <qapplication.h>
+#include <unistd.h>
#ifdef QT4_STATICPLUGIN_TEXTCODECS
#include <QtPlugin>
@@ -93,6 +94,7 @@ bool ConverterPrivate::convert() {
while (!convertionDone) {
QCoreApplication::processEvents();
QCoreApplication::sendPostedEvents();
+ usleep (100000);
}
return !error;
}
I added that usleep() because there's absolutely no reason to let that loop run away as it does. I've asked a few Qt developers about not using QApplication::exec() and they all say there is never a reason to NOT use it. The fact that you're using it in a library does not mean running QApplication::processEvents() in a loop provides you anything that QApplication::exec() doesn't. In fact, I argue that it's worse, because you end up with a runaway loop when your exit condition isn't met, which not only blocks, but consumes 100% of a CPU core.
@DanielCeregatti: using QApplication::exec
isn't simple, as this effectively means that calls to wkhtmltopdf_init
would never return. This part of wkhtmltopdf was written in the Qt 4.4 timeframe, so some of the solutions available now did not really exist or work properly then. I want to change it but don't really have the time for it right now...
On the network-related issue, can you check if it reproducible with 0.13
? Looks like Qt's network stack is not delivering some signals ... does putting a printf in PdfConverterPrivate::pagesLoaded
tell you if it has been reached?
Yes, this is reproducible in 0.13 and I'm also using the fix hangs branch. When the network issue is encountered, pagesLoaded is never called. It becomes stuck in the loop with no events and no way to exit the loop.
I've never used qt before and I primarily develop on windows platforms so forgive my lack of understanding of the qt framework.
Thanks for the confirmation. So what happens is that fail
never gets called and the loop remains running.
Yes, as a runaway thread using 100% of a CPU core, forever.
Can you change dumpFrameLoaderCallbacks
and dumpResourceLoadCallbacks
to true
around line 172
in qt/src/3rdparty/webkit/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
? Please paste the output, as Qt does not seem to be firing an event -- I suspect it is mostly due to dispatchDidFailLoading
not emitting a Qt signal. If that is the case, catching it will ensure that we call fail()
and hence getting out of the loop.
Ideally, I'd love to have a comparison of
@lndigo, @DanielCeregatti: any luck with the above procedure for getting diagnostics?
I haven't had a chance yet. I'll get to this some time after the holiday weekend here in the US.
@ashkulz
When the socket gets an EAGAIN from the read syscall, webkit never finishes loading the frame, so catching a dispatchDidFailLoading
doesn't seem to work since it is never emitted. It seems that QNetworkAccessManager
would provide a means to check for socket errors via the finished() and error() signal but it seems that the socket error does not get propogated up the chain from the from lower level classes like QIODevice\QNativeSocketEngine
and QHttpConnectionChannel
, since the error is not available from a QNetworkReply
object via QNetworkAccessManager
.
I delved into the webkit webcore trying to ascertain whether we could detect an error as an ErrorPageExtension
and pass it to a subclassed QWebPage
but as it currently stands the extension is never called despite being enabled in supportsExtension
. The code is quite complex and I was unable to determine a suitable location for a patch that would recognize the network error I was having and pass it to the page extension.
The fact that this error is happening all the way down in QIODevice/QAbstractSocket makes it difficult to solve the problem via inheritance.
Preliminary results show by modifying qnativesocketengine_unix.cpp
QNativeSocketEnginePrivate::nativeRead
, setting r = 0 in case EAGAIN will cause an error to be recognized by Qt; Qt handles it as an unexpected EOF and resends the current request which is desirable behavior. I don't know if this solution will work for @DanielCeregatti but it appears to work for my purposes.
I don't like patches that do not maintain the original intentions of the author and I'm sure causing an unexpectedEOF on any EAGAIN is not the cleanest way to solve the problem.
In addition, this is not an issue limited to wkhtmltox as I have reproduced it with Qt5.4.2 inside a QApplication:exec main loop, where it still produces a runaway thread.
I don't see why it would not work for me. As I've said before, I've suspected something like this was the problem all along. I'll give this a try as soon as I can. Good job hunting this down!
@Indigo: can you share your testcase? I'll try to push it upstream, possibly getting good feedback on the approach to be taken.
@ashkulz My test case is part of a project I've been developing internally for my employer. I don't feel comfortable sharing it publicly for privacy reasons but I could send you a working test case so that you can attempt to reproduce the bug and test the patch. If that is acceptable, send me a pm with contact information.
@Indigo: my email address is in my profile. Is it the pure Qt test case (what you referred to above) or one under wkhtmltopdf?
Pardon my ignorance, but I'm not very well versed in github. How exactly is this being addressed? It seems this bug is being sent upstream to the Qt people? Is there a bug report upstream that I can track?
I've built a new wkhtmltopdf with r = 0 set for EAGAIN in qnativesocketengine_unix.cpp but I've not had any chance to test. It seems to me this is really just a band-aid for the problem and that the final fix will be coming from upstream.
Please clarify.
@DanielCeregatti I sent @ashkulz my test case so that he can attempt to reproduce it.
I'm not sure what effect my patch would have on other projects and I agree that there exists a better solution that does not change the authors original intent. In my project, however, when the socket returns an EAGAIN from a read call, webkit never finishes loading the intended resource and therefore never finishes loading the frame, which leads me to an infinite loop.
You could attempt to patch the webkit engine, if the error is indeed in there, but I'm not familiar enough with the webkit engine to begin to make modifications to it. Additionally, webkit is being deprecated as of Qt5.5 so I see this as a fruitless endeavor.
If the error is not in the webkit engine, then it would need to be in the network access/socket code. But receiving an EAGAIN from a socket read is not an error and it's not an exception. So modifying the network code to report an EAGAIN as an error is not the correct solution either.
Additionally, none of this addresses the issue that the scenario only manifests when javascript is present.
Ultimately, by returning 0 on EAGAIN in nativeRead, Qt immediately resends the request for the resource for me and continues to load the frame uninhibited. Honestly, I couldn't ask for a better fix as I don't need notification of it, I just need it handled. Unfortunately, I don't have time on my side and for my purposes, the solution works but I understand reluctance to accept a solution that neglects to address the root problem: why is webkit not finishing loading the frame. This is @ashkulz project and I too would want to fix the root problem and not apply a band-aid.
I'm curious if my proposed fix works for your project @DanielCeregatti since that will at least verify whether we are experiencing the same issue. I'll continue to monitor this thread as I am interested in the final results and will assist in resolving the issue as time allows.
If this is an error with the networking code, then the testcase mentioned above
In addition, this is not an issue limited to wkhtmltox as I have reproduced it with Qt5.4.2 inside a QApplication:exec main loop, where it still produces a runaway thread.
would be very useful to report/fix upstream. I'll try to track down the issue with the wkhtmltopdf test case given by @Indigo, but finding the root cause may take some time. Will keep you posted if I find anything.
@Indigo Your fix does not work for me. Any time EAGAIN is encountered, the file it was retrieving fails to download. Here's my diff against wkhtmltopdf/qt@4be9ebb:
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 4bd9f98..94a0ec4 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -1039,7 +1039,8 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize)
#endif
case EAGAIN:
// No data was available for reading
- r = -2;
+ qDebug("EAGAIN...");
+ r = 0;
break;
case EBADF:
case EINVAL:
And here's a test run:
wkhtmltopdf --enable-javascript --load-error-handling abort --debug-javascript --cookie SESSIONID C264BAECF62C985CEBA9A9686EB5B942 --window-status waitEvent --orientation Landscape "URL REDACTED" test.pdf
Loading pages (1/6)
EAGAIN... ] 10%
EAGAIN...
EAGAIN...
EAGAIN...
EAGAIN... ] 10%
EAGAIN...
EAGAIN...
EAGAIN...
Warning: Failed to load URL_REDACTED/css/crossover.css (ignore)
Warning: Failed to load URL_REDACTED/css/notification.css (ignore)
Warning: URL_REDACTED/js/000_jquery/jquery-migrate-1.2.1.js:6 JQMIGRATE: Logging is active
EAGAIN...
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
Exit with code 1 due to network error: RemoteHostClosedError
A pdf is generated in this case, but since 2 CSS files didn't download, it's missing a lot of styling. On occasions where the files that fail to download are javascript files, the waitEvent never happens, as javascript never runs successfully.
One thing I've noticed is that despite setting "--load-error-handling abort", these events are always ignored. I'm guessing this is not what's supposed to happen?
Anyhow, can you post your test program where you reproduced this issue in Qt 5.4.2? I know a few people who write Qt applications and I'd like them to verify this and get it sent upstream once it's been verified.
@DanielCeregatti I was hopeful that the fix would work for you, looks like it's more complicated than I was hoping. Based on your response, can I assume that wkhtmltox no longer hangs? If that is the case, then I suppose this is at least progress, since now Qt is emitting errors instead of becoming a runaway thread.
In your instance, there is a counter that is initialized to 2, that decrements each time a resend request occurs, which setting r = 0 causes a resend request. Therefore, it appears to resend the request 3 times before failure. I suppose you could increase the initial value of the counter to increase the fault tolerance, however, I agree that the patching nativeRead is not going to be the solution. For curiosity's sake, I would be interested in what would happen if you increased the reconnectAttempts and if there exists a reasonable value that achieves a high success rate. Now, I'm not suggesting that is a fix, but I would like to know if it is a temporal communication issue between Qt and the webserver and perhaps by increasing the reconnectAttempts might extend the duration of the request window.
Lastly, I know everyone is busy and wants this problem solved. If @ashkulz is able to reproduce it with my source I'll send it to you @DanielCeregatti to submit to your colleagues. Oddly enough, when reducing the test case to its smallest size, I can get the error to occur even with no javascript being executed on the page. Makes me wonder about the JSLexer and maybe if I've wrote some funky javascript that it does not like...
I was not able to reproduce the error with the test case given by @Indigo. I tried the method given by @DanielCeregatti (killing the webserver while it is loading the page) -- created a 300kB file with just <br><hr>
and used a rate limit of 1kB/sec with extended_http_server.py. For me, it just gave:
Loading pages (1/6)
Warning: SSL error ignored
Error: Failed loading page https://localhost:8000/test.html (sometimes it will work just to ignore this error with --load-error-handling ignore)
Exit with code 1 due to network error: RemoteHostClosedError
So, I'm stumped. I can kind of understand the error path, but without being able to reproduce the error I can't really fix it inside Qt and/or WebKit (which is where it should ideally be fixed).
It is still my opinion that the underlying problem is the fact that javascript execution is interrupted or never started at all. In all test cases except the original few, --window-status is used. If javascript never sets the page's window.status when --window-status is used, wkhtmltopdf will hang indefinitely. For me the use of --window-status is mandatory, as our pages take a varying amount of time to load and I don't want to take a chance at having an incomplete pdf by using an arbitrary timer. Please retry your test with many script tags for javascript files and cause one of those to fail, along with --window-status. It will definitely hang.
@ashkulz @lndigo Can you please provide me with the Qt test case? If it can be shown that this is an upstream bug, it would go a long way in solving the problem, as I have the attention of a few Qt developers that can easily confirm if that is a valid test.
Edit: Apparently github comments break if you use <script> (without HTML entities) in a comment...
If there is a JS loading error and it hangs because of --window-status
, that's a separate issue ... very easy to reproduce but essentially unsolvable. @Indigo hasn't shared the Qt test case and you seem to suggest that your scenario is caused by using --window-status
... so did you ever get a hang without it?
I have no cases where I would use wkhtmltopdf without --window-status, so conducting such a test is futile for me. In my opinion, this bug is legitimate, but the underlying issue has not yet been entirely identified. My suspicion has always been that there is some sort of network error that's causing files to be omitted. @lndigo has alluded to this. This causes wkhtmltopdf to either never start javascript execution (such as omitting the file that handles winow.onload) or causes a javascript error which then prevents the code that sets window.status from running. I agree that this only affects people using --window-status.
I also agree with your assessment regarding the issue of tracking javascript execution as being "unsolvable". The problem remains though: wkhtmltopdf randomly hangs when --window-status is specified.
To be clear, I've conducted extensive testing on pages that I have loaded in Chrome hundreds of times and window.status is always set, yet wkhtmltopdf randomly does not start javascript on the exact same page. I have added a lot of console.log() calls to my javascript code to denote things like window.onload firing, asynchronous events happening, as well as window.status being set. When wkhtmltopdf hangs, no javascript output is ever seen, and accordingly, window.status is never set. So it's safe to conclude the hang is due to wkhtmltopdf waiting for window.status to be set when it's never going to be set.
At this time I'm going restate what I mentioned in an earlier comment: wkhtmltopdf needs more debugging output as well as more debugging features. It needs:
I've been granted more time to dig into this issue but I'm not sure how much more help I can offer given my limited understanding of C++. I'll report what I find as soon as I find it. That being said, I've been encountering some build issues recently. I can no longer build on my Debian Jessie machine. Even the master branch of a clean clone fails when building ruby gems in preparation for creating the chroot. I'll report more once I have more information.
Here's the build issue:
$ cat /etc/debian_version
8.1
$ sudo scripts/build.py setup-schroot-wheezy
...
lots of GETing
...
Building native extensions. This could take a while...
/usr/bin/ruby2.1 extconf.rb
checking for ffi.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/bin/ruby2.1
--with-ffi_c-dir
--without-ffi_c-dir
--with-ffi_c-include
--without-ffi_c-include=${ffi_c-dir}/include
--with-ffi_c-lib
--without-ffi_c-lib=${ffi_c-dir}/lib
--with-libffi-config
--without-libffi-config
--with-pkg-config
--without-pkg-config
/usr/lib/ruby/2.1.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
from /usr/lib/ruby/2.1.0/mkmf.rb:587:in `try_cpp'
from /usr/lib/ruby/2.1.0/mkmf.rb:1067:in `block in have_header'
from /usr/lib/ruby/2.1.0/mkmf.rb:918:in `block in checking_for'
from /usr/lib/ruby/2.1.0/mkmf.rb:351:in `block (2 levels) in postpone'
from /usr/lib/ruby/2.1.0/mkmf.rb:321:in `open'
from /usr/lib/ruby/2.1.0/mkmf.rb:351:in `block in postpone'
from /usr/lib/ruby/2.1.0/mkmf.rb:321:in `open'
from /usr/lib/ruby/2.1.0/mkmf.rb:347:in `postpone'
from /usr/lib/ruby/2.1.0/mkmf.rb:917:in `checking_for'
from /usr/lib/ruby/2.1.0/mkmf.rb:1066:in `have_header'
from extconf.rb:16:in `<main>'
ERROR: Error installing fpm:
ERROR: Failed to build gem native extension.
Building has failed. See above output for more information on the failure.
extconf failed, exit code 1
Gem files will remain installed in /var/lib/gems/2.1.0/gems/ffi-1.9.10 for inspection.
Results logged to /var/lib/gems/2.1.0/extensions/x86_64-linux/2.1.0/ffi-1.9.10/gem_make.out
gem install -V fpm -N
command failed: exit code 256
@DanielCeregatti: let us discuss the build issue in the linked issue instead of here. I've only tested the generic linux builds, not the distro-specific builds (and that too not on a fresh machine), hence the problem. The 0.12.3
release will only be with generic linux builds, not sure right now if the other targets will still be kept in the build script or removed.
wkhtmltopdf needs more debugging output as well as more debugging features. It needs:
- To print when it starts to download a page asset file. (Image, javascript, css, whatever)
- To print when it finishes downloading a file, along with statistics.
Those are "good to have", not essential to solving this issue.
- An option to turn off the progress bar. It just gets in the way when you're trying to read the output.
Use the -q
or --quiet
option.
- An option to exit execution with a non zero status when any page asset file fails to load. It seems that neither --load-error-handling abort and --load-media-error-handling abort do this.
That's clearly a bug, can you create a very small test case to confirm it? Please attach it to a separate issue so that it can be fixed separately.
- An option to time the whole thing out when --window-status is used.
That's a new feature, maybe something like --window-status-timeout
? Report a separate issue to track it.
I'd like to leave this issue open to identify if there truly are random hangs happening without the --window-status
option, which @Indigo seems to be experiencing.
The -q or --quiet option suppresses all output. I still need to see everything javascipt is writing to the console. I just want to suppress the progress bar.
Do you mean an option like --disable-progressbar
which would still show all warning/error messages?
Sorry for the long hiatus. I've been very busy.
Yes, if the progress output could be suppressed, that would be a nice feature to have. My strategy now is to simply mitigate when wkhtmltopdf hangs, and doing so involves reading its output.
I have confirmed that wkhtmltopdf can hang on simply downloading content without --window-status. It's still very hit and miss, and I can't create a consistently reproducible example.
Today I ran into this other bug report: #2234. That backtrace looks all too familiar. I'm going play around with those settings to see if they help.
Version: 0.12.2.1 (with patched qt), same with 0.12.1 OS: Ubuntu 3.13.0-44-generic #73-Ubuntu SMP Tue Dec 16 00:22:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
1) OS is a completely clean new "install". 2) sudo apt-get install gdebi 3) sudo gdebi wkhtmltox-0.12.2.1_linux-jessie-amd64-2.deb 4) Then i just
wkhtmltopdf "http://lenta.ru" lenta.pdf
lenta.ru is a news web site, so the content is updated frequently. So to be sure contents is
not changed - you can check my web page -
wkhtmltopdf "http://www.adaperio.ru/engine.html#/search/%D0%BD030%D1%80%D0%BD98" sample.pdf
Output:
Unable to load library icui18n "Cannot load library icui18n: (icui18n: cannot open shared object file: No such file or directory)" Loading pages (1/6) Fontconfig warning: ignoring UTF-8: not a valid region tag ] 50% [======================================================> ] 90%
And it freezes (for 2-5 hours easily). Sometimes it is OK and process finishes normally with good PDF file. Please run several times.
The end of "strace -f -e trace=network -s 10000 wkhtmltopdf "http://lenta.ru" lenta.pdf" output is: [pid 1301] setsockopt(29, SOL_SOCKET, SO_OOBINLINE, [1], 4) = 0 [pid 1301] connect(29, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("54.243.146.98")}, 16) = -1 EINPROGRESS (Operation now in progress) [pid 1301] connect(29, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("54.243.146.98")}, 16) = 0 [pid 1301] getsockname(29, {sa_family=AF_INET, sin_port=htons(59900), sin_addr=inet_addr("172.31.5.30")}, [16]) = 0 [pid 1301] getpeername(29, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("54.243.146.98")}, [16]) = 0 [pid 1301] getsockopt(29, SOL_SOCKET, SO_TYPE, [1], [4]) = 0 [pid 1301] setsockopt(29, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0 ...and then freezes...
On my MAC OS X the same worked fine 10/10 times. Output: "Loading pages (1/6) Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6) Done
Exit with code 1 due to network error: HostNotFoundError" (but its ok and PDF is generated)
Please help. Thank you!