Bug 425188 - Okular crashes opening PDFs from other apps
Summary: Okular crashes opening PDFs from other apps
Status: RESOLVED FIXED
Alias: None
Product: okular
Classification: Applications
Component: general (show other bugs)
Version: 1.10.1
Platform: Ubuntu Linux
: NOR crash
Target Milestone: ---
Assignee: Okular developers
URL:
Keywords:
: 426297 426698 430972 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-08-10 13:57 UTC by Corrado Mella
Modified: 2021-01-04 23:28 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In: 20.12
Sentry Crash Report:


Attachments
Report from KDE Crash handler (7.82 KB, text/plain)
2020-08-10 13:57 UTC, Corrado Mella
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Corrado Mella 2020-08-10 13:57:37 UTC
Created attachment 130753 [details]
Report from KDE Crash handler

SUMMARY
Okular crashes opening PDFs from Thunderbird.
New behaviour since upgrading Kubuntu 18.04.4 LTS to 20.02.1 LTS.

STEPS TO REPRODUCE
1. Open Thunderbird (v.68.10.0 as in current repos) and set Okular as handler for PDF attachments.
2. Select a message with a PDF attachment to preview it in the preview pane
3. Click on the PDF attachment to open it on Okular

OBSERVED RESULT
Okular crashes with a segfault

EXPECTED RESULT
PDF opening

SOFTWARE/OS VERSIONS
Linux/KDE Plasma: 
(available in About System)
KDE Plasma Version: 5.18.15
KDE Frameworks Version: 5.68.0
Qt Version: 5.12.8

ADDITIONAL INFORMATION
Kernel Version: 5.4.0-42-generic 64-bit
Comment 1 Corrado Mella 2020-08-10 14:14:53 UTC
Correction

Okular crashes on opening a PDF file from ANY application.
Dolphin, command line, etc.

Opening the same file from its "File | Open..." menu succeeds.
Comment 2 Nate Graham 2020-08-10 21:00:40 UTC
Thread 1 (Thread 0x7f5185bb1800 (LWP 12569)):
[KCrash Handler]
#6  0x00007f5189924ea4 in QScreen::size() const () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#7  0x00007f5189925071 in QScreen::physicalDotsPerInchY() const () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#8  0x00007f518a2b6d96 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#9  0x00007f518a2b9f9c in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00007f518a2bb48f in QScroller::scrollTo(QPointF const&, int) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#


That's odd.
Comment 3 Laura David Hurka 2020-08-10 21:44:45 UTC
Now my theory is that it will crash when you enable tabs and open a file from File -> Open. Right? (Settings -> Configure Okular -> General -> Open new files in tabs)

QScroller appears to access screen() of PageView although it hasn’t been shown yet. I think there was another bug much like this some weeks ago, don’t remember which.

Can you try to install the debugging symbols and generate a new backtrace? If that works, it could make our job easier.
Comment 4 Albert Astals Cid 2020-08-10 22:11:59 UTC
This is a duplicate, as far as i remember someone else was having this QScreen crash
Comment 5 Albert Astals Cid 2020-09-08 10:26:22 UTC
*** Bug 426297 has been marked as a duplicate of this bug. ***
Comment 6 Nate Graham 2020-09-18 21:30:51 UTC
*** Bug 426698 has been marked as a duplicate of this bug. ***
Comment 7 Laura David Hurka 2020-10-21 15:50:01 UTC
@anyone who can still reproduce this bug:

I created a small test application using Qt’s test framework in https://invent.kde.org/davidhurka/qscrollertest . If you are able to run this test on your setup and tell us the results, that would be great! :)

I am not able to reproduce the problem on my system. My test output is here as reference:
> ********* Start testing of QScrollerTest *********
> Config: Using QtTest library 5.15.0, Qt 5.15.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 9.3.0)
> PASS   : QScrollerTest::initTestCase()
> QDEBUG : QScrollerTest::testWidgetScreen() Screen before showing widget: QScreen(0x55f55187aa20, name="eDP-1")
> QDEBUG : QScrollerTest::testWidgetScreen() Screen after showing widget: QScreen(0x55f55187aa20, name="eDP-1")
> PASS   : QScrollerTest::testWidgetScreen()
> QDEBUG : QScrollerTest::testQScrollerOnNotShownWidget() Scrolling a not shown widget.
> PASS   : QScrollerTest::testQScrollerOnNotShownWidget()
> QDEBUG : QScrollerTest::testQScrollerOnShownWidget() Scrolling a shown widget.
> PASS   : QScrollerTest::testQScrollerOnShownWidget()
> PASS   : QScrollerTest::cleanupTestCase()
> Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted, 23ms
> ********* Finished testing of QScrollerTest *********
Comment 8 Laura David Hurka 2020-10-27 18:08:37 UTC
Another idea: Can this be an issue of broken ABI? Like when Qt Widgets was compiled against a different minor release of Qt Gui than our users are using, and Qt Gui broke their ABI in this minor release. So that something in Qt Widgets reads from a Qt Gui object with a slight address offset, so it gets this weird enum value instead of the correct pointer?
Comment 9 Albert Astals Cid 2020-10-27 19:02:12 UTC
(In reply to David Hurka from comment #8)
> Another idea: Can this be an issue of broken ABI? Like when Qt Widgets was
> compiled against a different minor release of Qt Gui than our users are
> using, and Qt Gui broke their ABI in this minor release. So that something
> in Qt Widgets reads from a Qt Gui object with a slight address offset, so it
> gets this weird enum value instead of the correct pointer?

Given how much people have this QScroller crash, doesn't seem reasonable to me ot to expect they all have broken systems.
Comment 10 Laura David Hurka 2020-11-08 11:12:11 UTC
For those who still suffer from this crash: Make sure that your screen arrangement contains the point (0, 0). Alternatively, upgrade to Qt >= 5.14.

Yesterday we could reproduce and debug this crash by chance. My test application did not compile, because QWidget::screen() is only available since Qt 5.14. And that is the point: You use Qt 5.12, where QWidget::screen() does not exist yet.

QScroller uses QDesktopWidget instead, but QDesktopWidget returns screen -1 when the widget does not (yet) intersect with a physical screen. QScroller does not check for -1, and silently fetches the QScreen* pointer at position -1. This position is some QList internal data, so the application does not crash there yet. So, instead of a pointer, QScroller reads your screen *count* with an offset of 32 bit. This is why the backtraces contain this=0x300000000.

I reported this bug at https://bugreports.qt.io/browse/QTBUG-88288.

Until Okular requires Qt >= 5.14, we will need protecting code in PageView, which enlarges the widget if it does not intersect with physical screens.
Comment 11 Laura David Hurka 2020-11-08 12:23:34 UTC
Git commit 7bac65ed6824d078abf6d49aab43b27a9ec7362f by David Hurka.
Committed on 08/11/2020 at 12:19.
Pushed by davidhurka into branch 'fix-qscroller-screen-crash'.

Fix QScroller crash on Qt < 5.14 and certain screen arrangements

QScrollerPrivate::setDpiFromWidget() before Qt 5.14 crashes
when the target widget does not intersect a physical screen,
because QDesktopWidget returns screen index `-1` in this case,
which leads to an out-of-range read from QApplication::screens(),
which leads to a segfault when reading from an invalid QScreen* pointer.

This adds a workaround that checks for the `-1` situation,
and then tries to resize PageView temporarily to intersect at least some screen.
FIXED-IN: 20.12

M  +15   -0    ui/pageview.cpp

https://invent.kde.org/graphics/okular/commit/7bac65ed6824d078abf6d49aab43b27a9ec7362f
Comment 12 David 2020-11-08 12:29:14 UTC
This makes a lot of sense. I suppose I can test the observation by swapping my monitors around which will mean that (0, 0) is visible. I would be waiting for OpenSuse to push the latest Qt out.

I'm wondering if this is also what is driving KDE to do weird screen placement when plugging in and unplugging the monitor, causing the screen blanking to fail on idle, preventing rectangular screen grab from working correctly, and messing up the touch screen co-ordinates for the left screen laptop.

I'll need to test when I can.
Comment 13 Laura David Hurka 2020-11-08 12:31:27 UTC
Sorry, I typed origin_invent instead of origin_fork, which closed this automatically. :/
Comment 14 Bug Janitor Service 2020-11-08 12:38:59 UTC
A possibly relevant merge request was started @ https://invent.kde.org/graphics/okular/-/merge_requests/314
Comment 15 Laura David Hurka 2020-11-20 19:00:37 UTC
Git commit c6a3275151ffa5c9045c8186b64e45e4b2c3ccbf by David Hurka.
Committed on 20/11/2020 at 18:01.
Pushed by davidhurka into branch 'release/20.12'.

Fix QScroller crash on Qt < 5.14 and certain screen arrangements

QScrollerPrivate::setDpiFromWidget() before Qt 5.14 crashes
when the target widget does not intersect a physical screen,
because QDesktopWidget returns screen index `-1` in this case,
which leads to an out-of-range read from QApplication::screens(),
which leads to a segfault when reading from an invalid QScreen* pointer.

This adds a workaround that checks for the `-1` situation,
and then tries to resize PageView temporarily to intersect at least some screen.
FIXED-IN: 20.12

M  +15   -0    part/pageview.cpp

https://invent.kde.org/graphics/okular/commit/c6a3275151ffa5c9045c8186b64e45e4b2c3ccbf
Comment 16 Nate Graham 2021-01-04 23:28:28 UTC
*** Bug 430972 has been marked as a duplicate of this bug. ***