Details
Description
I've gotten ~50 crash reports from qutebrowser users since August, where they get a segfault when I call QWebEngineDownloadItem::page(). Some (but not all!) say it was when retrying a download. However, even with various scenarios (e.g. closing a tab a download was made from, disconnecting my connection so it fails, and then retrying it), I never was able to reproduce.
Upstream report: https://github.com/qutebrowser/qutebrowser/issues/7854
Relevant parts of the stacktrace:
Core was generated by `/usr/bin/python3 /usr/bin/qutebrowser'. Program terminated with signal SIGSEGV, Segmentation fault. #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=11, no_tid=no_tid@entry=0) at pthread_kill.c:44 Downloading source file /usr/src/debug/glibc/glibc/nptl/pthread_kill.c 44 return INTERNAL_SYSCALL_ERROR_P (ret) ? INTERNAL_SYSCALL_ERRNO (ret) : 0; [Current thread is 1 (Thread 0x7fcf5f24d740 (LWP 972774))] (gdb) bt full #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=11, no_tid=no_tid@entry=0) at pthread_kill.c:44 tid = <optimized out> ret = 0 pd = <optimized out> old_mask = {__val = {0}} ret = <optimized out> #1 0x00007fcf5e88e8a3 in __pthread_kill_internal (signo=11, threadid=<optimized out>) at pthread_kill.c:78 #2 0x00007fcf5e83e668 in __GI_raise (sig=11) at ../sysdeps/posix/raise.c:26 ret = <optimized out> #3 0x00007fcf5e83e710 in <signal handler called> () at /usr/lib/libc.so.6 #4 0x00007fcf50d453e7 in QWebEngineDownloadRequest::page() const (this=<optimized out>) at /usr/src/debug/qt6-webengine/qtwebengine-everywhere-src-6.5.2/src/core/api/qwebenginedownloadrequest.cpp:604 #5 0x00007fcf3da26450 in meth_QWebEngineDownloadRequest_page(PyObject*, PyObject*) (sipSelf=<optimized out>, sipArgs=<optimized out>) at /usr/src/debug/pyqt6-webengine/PyQt6_WebEngine-6.5.0/build/QtWebEngineCore/sipQtWebEngineCoreQWebEngineDownloadRequest.cpp:545 sipRes = <optimized out> sipCpp = 0x7fceec2c6820 sipParseErr = 0x0 [Python / PyQt internals] #20 0x00007fcf50d61978 in QWebEngineProfile::downloadRequested(QWebEngineDownloadRequest*) (_t1=0x7fceec2c6820, this=0x558dfba2b0e0) at /usr/src/debug/qt6-webengine/build/src/core/api/WebEngineCore_autogen/include/moc_qwebengineprofile.cpp:213 _a = {0x0, 0x7ffd9a680cb0} q = 0x558dfba2b0e0 itemPrivate = <optimized out> download = 0x7fceec2c6820 state = <optimized out> #21 QWebEngineProfilePrivate::downloadRequested(QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo&) (this=0x558dfba2c090, info=...) at /usr/src/debug/qt6-webengine/qtwebengine-everywhere-src-6.5.2/src/core/api/qwebengineprofile.cpp:213 q = 0x558dfba2b0e0 itemPrivate = <optimized out> download = 0x7fceec2c6820 state = <optimized out> #22 0x00007fcf4d72ad95 in QtWebEngineCore::DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*, base::OnceCallback<void (base::FilePath const&, download::DownloadItem::TargetDisposition, download::DownloadDangerType, download::DownloadItem::MixedContentStatus, base::FilePath const&, base::FilePath const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, download::DownloadInterruptReason)>*) () at /usr/src/debug/qt6-webengine/qtwebengine-everywhere-src-6.5.2/src/core/download_manager_delegate_qt.cpp:161 #23 0x00007fcf4f9fe40b in content::DownloadManagerImpl::DetermineDownloadTarget(download::DownloadItemImpl*, base::OnceCallback<void (base::FilePath const&, download::DownloadItem::TargetDisposition, download::DownloadDangerType, download::DownloadItem::MixedContentStatus, base::FilePath const&, base::FilePath const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, download::DownloadInterruptReason)>) () at ../../../../../qtwebengine-everywhere-src-6.5.2/src/3rdparty/chromium/content/browser/download/download_manager_impl.cc:496 #24 0x00007fcf4f602c3f in download::DownloadItemImpl::DetermineDownloadTarget() () at ../../../../../qtwebengine-everywhere-src-6.5.2/src/3rdparty/chromium/components/download/internal/common/download_item_impl.cc:1699 #25 0x00007fcf4f60fb71 in base::RepeatingCallback<void (download::DownloadInterruptReason, long)>::Run(download::DownloadInterruptReason, long) && () at ../../../../../qtwebengine-everywhere-src-6.5.2/src/3rdparty/chromium/base/functional/callback.h:278 #26 download::DownloadJob::OnDownloadFileInitialized(base::RepeatingCallback<void (download::DownloadInterruptReason, long)>, download::DownloadInterruptReason, long) () at ../../../../../qtwebengine-everywhere-src-6.5.2/src/3rdparty/chromium/components/download/internal/common/download_job.cc:75 [Chromium internals]
From IRC:
09:04 <carewolf_home> right, so page might be null? 09:33 <mibrunin> carewolf_home: I looking at the trace, it might be a segfault because the adapterClient in QWebEnginePagePrivate is null for some reason 09:34 <mibrunin> sorry, in QWebEngineDownloadRequest 09:39 <mibrunin> we're accessing it without checking for null even though there are cases where it gets initialised to nullptr 09:40 <mibrunin> The-Compiler: I think it would make sense to file a bug - we can insert a null check as a speculative fix
Attachments
For Gerrit Dashboard: QTBUG-119763 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
523369,3 | Fix unconditional pointer access in QWebEngineDownloadRequest::page | dev | qt/qtwebengine | Status: MERGED | +2 | 0 |
523768,2 | Fix unconditional pointer access in QWebEngineDownloadRequest::page | 6.6 | qt/qtwebengine | Status: MERGED | +2 | 0 |
523983,2 | Fix unconditional pointer access in QWebEngineDownloadRequest::page | 6.5 | qt/qtwebengine | Status: MERGED | +2 | 0 |