# qt-5.11: bus error bei qpdfview, avidemux [solved]

## mv

Mit qt-5.11 habe ich reproduzierbar beim Start von qpdfview oder avidemux einen Bus-Fehler (schon beim reinen Start ohne Argumente):

Das Fenster öffnet sich kurz, und mit gdb (wenn ich mit debug-Informationen übersetze) bin ich ziemlich sicher, dass die Funktion, die das Fenster löschen soll, den Bus-Fehler bringt.

(Je nachdem ob ich mit oder ohne egl und/oder xcb übersetze, sind das andere Funktion, aber jeweils dort kommt der Bus-Fehler).

Das Problem tritt sowohl mit qt-5.11.1::gentoo als auch mit qt-5.11.2::qt (also aus dem qt-Overlay) auf.

Ich habe sowohl alle qt*-Pakete als auch etliche Abhängigkeiten mit i.W. nur -march=native -O2 neu übersetzt (normalerweise nutze ich experimentellere CFLAGS) und habe bei qtgui schon verschiedene USE-Flag-Kombinationen probiert.

Das Problem tritt bei mehreren Rechnern (sowohl in x86 als auch amd64) auf. Im Moment ist mir schleierhaft, weshalb das überhaupt bei irgendjemandem gehen sollte, aber ich habe schon im englischen Forum gefragt, und dort hatte niemand ähnliche Probleme.

Hat jemand noch irgendeine Idee?Last edited by mv on Fri Nov 02, 2018 3:47 pm; edited 1 time in total

----------

## Tyrus

Also ich hab grade mal extra qpdfview installiert. Die stable Version 0.4.16 läuft ohne Probleme. Habs von der Kommandozeile gestartet mit verschiedenen PDF-Quellen. Es kam nie eine Ausgabe über die Kommandozeile.

USE-Flags hier waren: +cups, +dbus, +pdf, +sqlite, +svg

CFLAGS="-march=native -O2 -pipe"

Für pdf:

app-text/poppler: 0.62.0-r1

dev-qt/qtxml: 5.11.1

dev-qt/qtgui-5.11.1 schaut so aus:

```

mithrandir@luthien ~ $ equery u dev-qt/qtgui

[ Legend : U - final flag setting for installation]

[        : I - package is installed with flag     ]

[ Colors : set, unset                             ]

 * Found these USE flags for dev-qt/qtgui-5.11.1:

 U I

 + + accessibility : Add support for accessibility (eg 'at-spi' library)

 + + dbus          : Enable dbus support for anything that needs it (gpsd, gnomemeeting, etc)

 - - debug         : Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see

                     https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces

 + + egl           : Enable EGL integration

 + + eglfs         : Build the EGL Full Screen/Single Surface platform plugin

 + + evdev         : Enable support for input devices via evdev

 + + gif           : Add GIF image support

 + + ibus          : Build the IBus input method plugin

 + + jpeg          : Add JPEG image support

 + + libinput      : Enable support for input devices via dev-libs/libinput

 + + png           : Add support for libpng (PNG images)

 - - test          : Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled

                     independently)

 - - tslib         : Enable support for touchscreen devices via x11-libs/tslib

 - - tuio          : Build plugin to receive touch events over the TUIO protocol

 + + udev          : Enable virtual/udev integration (device discovery, power and storage device support, etc)

 - - vnc           : Enable VNC (remote desktop viewer) support

 + + xcb           : Build the XCB platform plugin and enable X11 integration

```

----------

## Josef.95

 *mv wrote:*   

> Das Problem tritt bei mehreren Rechnern (sowohl in x86 als auch amd64) auf. 

  Wird auf all diesen Systemen zufällig der xf86-video-intel Treiber genutzt?

----------

## mv

 *Josef.95 wrote:*   

>  *mv wrote:*   Das Problem tritt bei mehreren Rechnern (sowohl in x86 als auch amd64) auf.   Wird auf all diesen Systemen zufällig der xf86-video-intel Treiber genutzt?

 

Jein: Der modesetting driver. VIDEO_CARDS="intel i965", media-libs/mesa-18.2.0-r1. xorg-server-1.20.1[glamor systemd udev wayland xnest xorg xvfb]

xf86-video-intel selbst ist aber nicht installiert.

Sind damit Probleme im Zusammenhang mit qt-5.11 bekannt?

Ich sehe gerade, dass es inzwischen neue Versionen von mesa und xorg-server gibt. Mal sehen, ob die das Problem lösen.

----------

## Josef.95

 *mv wrote:*   

> Sind damit Probleme im Zusammenhang mit qt-5.11 bekannt?

  Hm nein, das war eher nur eine Vermutung (von dem Treiber gibt es schon seit Jahren kein Release mehr).

----------

## firefly

Trotzdem könnte es einen zusammenhang mit der Intel iGPU und dem Problem geben.

AFAIK verwendet Qt beim rendern opengl, wenn nicht anders konfiguriert/angegeben.

Bei mir tritt das Problem nicht auf und ich habe eine AMD dGPU im Einsatz. Wenn das Problem genereller Natur wäre müsste ich es eigendlich auch sehen, da ich KDE Plasma 5 als Desktop verwende.

----------

## asturm

Kein Problem hier mit der Intel GPU.

----------

## mv

 *firefly wrote:*   

> AFAIK verwendet Qt beim rendern opengl, wenn nicht anders konfiguriert/angegeben.

 

Wie kann man konfigurieren, dass qt kein opengl benutzt?

----------

## mike155

Ich habe auch eine Intel GPU, Kernel 4.14, modesetting Treiber, Wayland, KDE GUI und seit Juli qt-5.11.1, seit gestern qt-5.11.2. qdpfview läuft einwandfrei und es gibt keine Bus-Fehler oder Abstürze.

@mv: verwendet Du "exotische" USE-Flags wie "opencl" oder "gles2"?

----------

## mv

Mesa: classic dri3 egl gallium gbm gles2 llvm pic wayland

xorg-server: glamor systemd udev wayland xnest xorg xvfb

Wenn man den Wayland-compositor von weston will (und ohne den kein Wayland, oder?), kommt man um mesa[gles2] nicht herum.

----------

## asturm

 *mv wrote:*   

> Wenn man den Wayland-compositor von weston will (und ohne den kein Wayland, oder?), kommt man um mesa[gles2] nicht herum.

 

Weston ist irrelevant, außer man verwendet einen WM der nicht sein eigener Compositor ist (was KWin für Plasma erledigt). Letzterer braucht auch mesa[gles2], aber das ist auch nicht das Problem (Qt mit gles2 wäre das gewesen, und alle anderen Toolkits die full GL bei gles2 deaktivieren).

----------

## mv

qtgui hat derzeit: dbus egl gif jpeg libinput png udev xcb

Aber ich habe es auch schon ohne dbus, egl, libinput, udev und xcb probiert - selbes Ergebnis.

----------

## mike155

 *mv wrote:*   

> Mesa: classic dri3 egl gallium gbm gles2 llvm pic wayland
> 
> xorg-server: glamor systemd udev wayland xnest xorg xvfb 

 

Bei den beiden Paketen habe ich ähnliche USE Flags:

* mesa: classic dri3 egl gallium gbm gles2 nptl osmesa vaapi wayland. --> Unterschied: vaapi, llvm, pic 

* xorg-server: glamor systemd udev wayland xorg. --> Unterschied: xnest, xvfb

Bei der Frage nach "gles2" und "opencl" dachte ich eher an kwin, qtgui, qtwidgets, qtprintsupport, ... Ich habe das USE Flag "gles2" nur bei weston und mesa aktiviert. Und "opencl" habe ich bei keinem Paket aktiviert.

----------

## mv

Wieder viele neue Möglichkeiten versucht (Upgrade von xorg-server, mesa, Kompilierung von mesa ohne gles2, Kompilierung von qtgui ohne egl usw.).

Selbes Resultat: Immer sofortiger Bus-Fehler.

Wie gesagt kommt der Fehler schon so früh (beim reinem Löschen einen Fensters) und zwar nur mit >=qt-5.11, dass ich mir schon gar nichts mehr anderes vorstellen kann, als dass >=qt-5.11 eine kaputte Logik hat und von vornherein versucht, einen Bereich zu löschen, der außerhalb des Fensters liegt o.ä.

Ich werde wohl bei qt-5.9.6 bleiben müssen. Aber was mache ich in eniem halben Jahr, sobald die Programme anfangen werden, qt-5.11 vorauszusetzen   :Crying or Very sad: 

----------

## mv

Mein letzter Strohhalm war, dass es am windowsmanager liegen könnte (hier: fvwm), aber auch mit xfce kommt der Bus-Fehler.

----------

## Falmer

Bei mir läuft seit dem update von qt-5.11.1 auf 5.11.2 der windowmanger (enlightenment) nicht mehr.

Zum Glück habe ich das update zuerst nur auf meinem Zweitrechner gemacht.

So tief wie mv kann ich nicht nachverfolgen, woran das liegt.

Auf jeden Fall passiert es mit dem enlightement aus dem Gentoo-Repo, als auch mit einem (aktuelleren) aus den offiziellen Releases.

Gruß

Falmer

----------

## mv

OK, jetzt habe ich ein Minmalbeispiel:

 *a.cc wrote:*   

> #include <QApplication>
> 
> #include <qframe.h>
> 
> int main(int argc, char ** argv) {
> ...

 

 *a.pro wrote:*   

> TARGET  = a
> 
> SOURCES = a.cc
> 
> QT += widgets

 

 *failure wrote:*   

> qmake && make && ./a
> 
> rm a a.o .qmake.stash Makefile

 

Läuft mit qt-5.9.6, bus error mit qt-5.11 und qt-5.12.

Ich bin kein Experte in Qt, und das obige Minimalbeispiel habe ich aus kccmp (das ebenfalls crasht) zusammengefrickelt: Mache ich da etwas falsch?

----------

## Tyrus

@mv:

Hab dein Beispiel 1:1 so getestet. Benutze selber qt-5.11.2.

Das Beispiel funktioniert ohne irgendeine Fehlermeldung. Ich bekomme ein Fenster (das QFrame) angezeigt, das in der Titelzeile mit "a" benannt ist und den WindowsClose-Event auch kann.

Leider fällt mir auch nichts neues ein, das den Unterschied erklären könnte ... *grübel*

----------

## mv

Danke. Vermutlich werde ich einen Bugreport an qt schreiben müssen.

Aber als ich mir da einen Login machen wollte, war in den Geschäftsbedingungen, die man akzeptieren muss, von "License fees" die Rede.

Jetzt traue ich mich nicht mehr: Am Schluss wird der Bugreport als support request angesehen, und ich bekomme eine horrende Rechnung...

----------

## mike155

Das kurze Testprogramm, mit dem man den Fehler reproduzieren kann, ist klasse.

Aber ist denn gesagt, dass der Fehler wirklich bei Qt liegt? Immerhin funktioniert das Testprogramm bei mir und vermutlich auch bei den meisten anderen. Und 'ldd a' zeigt, dass etliche Shared Libraries eingebunden werden. Ich würde den Fehler eigentlich eher irgendwo dort vermuten... Kannst Du mit dem Debugger herausfinden, in welcher Shared Library und Funktion der Fehler passiert?

----------

## mv

 *mike155 wrote:*   

> Aber ist denn gesagt, dass der Fehler wirklich bei Qt liegt?

 

Das klingt halt sehr wahrscheinlich, da es mit qt-5.9 auf all meinen Systemen reproduzierbar funktioniert, und bei >=qt-5.11 eben nicht. Klar kann es sein, dass >=qt-5.11 irgendeine Blbliothek anders anspricht und nur dadurch einen Bug triggert, der vorher nicht aufgetreten ist, aber sehr wahrscheinich scheint das nicht zu sein.

 *Quote:*   

> Kannst Du mit dem Debugger herausfinden, in welcher Shared Library und Funktion der Fehler passiert?

 

Ich dachte, das hätte ich schon im Eröffnungsposting beschrieben, aber das war wohl doch etwas zu knapp:

 *Quote:*   

> gdb --args ./a
> 
> [...]
> 
> (gdb) run
> ...

 

(X11 ist nicht mit debugging-Optionen übersetzt, aber qtgui schon).

Der Crash scheint in der Funktion aufzutreten, in der vermutlich der Fensterinhalt gelöscht werden soll. Wenn ich mit Optionen/USE-Flags herumspiele, tritt der Bus-Fehler statt in qt_memfill32 in qt_memfill_sse (oder so ähnlich) auf (Detalis habe ich im Moment vergessen): Es ist wohl nicht die Fill-Funktion selbst, die fehlerhaft ist, sondern sie wird vermutlich mit falschen Parametern aufgerufen.

----------

## mike155

Danke für den Backtrace - jetzt verstehe ich es auch.

Wenn ich Deinen Fehler reproduzieren könnte, würde ich jetzt mit dem Debugger suchen. Beispielsweise würde ich mir die Parameter ansehen, die bei fillRect_normalized() und qt_memfill32() übergeben werden (vielleicht sieht man dort bereits etwas - es ist ja ein SIGBUS, und kein SIGSEGV) und versuchen herauszufinden, wo sie eigentlich herkommen. Aber das ist natürlich alles sehr, sehr mühsam...

----------

## mv

 *mike155 wrote:*   

> Vielleicht sieht man dort bereits etwas - es ist ja ein SIGBUS, und kein SIGSEGV

 

Was das heißt, ist mir nicht ganz klar: Ich hatte natürlich ebenfalls zuerst an falsches Alignment (oder nullptr) gedacht. Scheint aber beides nicht zuzutreffen. Soweit ich das beurteilen kann, sehen die Werte „vernünftig“ aus.

Woher die Werte kommen, kann ich nicht nachvollziehen; das Ganze findet wohl innerhalb eines Subthreads von qt statt, und das ist ohne tieferes Verständnis von qt schwer zu durchschauen.

Übrigens habe ich jetzt mal mesa ohne Support für irgendeine Graphikkarte kompiliert: Es kommen Fehler, dass die betreffenden Treiber nicht geladen werden können, aber danach scheint es in einem "fallback"-Modus weiterzugehen. Es blinkt dann wieder kurz ein Fesnterrahmen auf, und danach kommt der bekannte Bus-Fehler.

----------

## mike155

Nehmen wir an, dass folgendes passiert:

Beim Erstellen des Fensters ruft Qt eine Funktion auf (vermutlich über eine Reihe weiterer Funktionen), die einen Speicherbereich für das Fenster (Surface) bereitstellt. Nennen wir sie vorläufig "win_mem_alloc()". In Wirklichkeit heißt sie natürlich anders.

Qt schreibt dann in den zurückgegebenen Speicherbereich, um das Fenster zu löschen. Dabei läuft etwas schief - und es gibt den SIGBUS.

Es gibt mehrere Möglichkeiten:

Es gibt einen einen Fehler in Qt bei dem Aufruf von win_mem_alloc() oder beim Löschen des Fensters. 

Das ist unwahrscheinlich, weil das auch bei anderen Leuten auffallen würde.

Es gibt einen Fehler in win_mem_alloc() und die Funktion signalisiert in den Rückgabewerten eine Fehler. Allerdings funktioniert die Fehlererkennung und -behandlung von Qt nicht. Qt macht weiter, als ob alles in Ordnung wäre. Beim Schreiben in das Fenster gibt es dann einen SIGBUS. 

In diesem Fall gäbe es einen Fehler in der Fehlererkennung von Qt und einen Fehler in win_mem_alloc().

Es gibt einen Fehler in win_mem_alloc(), aber win_mem_alloc() signalisiert keinen Fehler. Deswegen denkt Qt, dass alles in Ordnung sei und macht weiter. Sobald Qt in das Fenster schreibt, gibt es einen SIGBUS. 

In diesem Fall gibt es keinen Fehler in Qt, aber einen Bug in win_mem_alloc().

Ich würde auf (2) oder (3) tippen. Die Frage ist nun, welches Modul  win_mem_alloc() auf Deinem System bereitstellt:

Hast Du ein Wayland-System? Dann wird  win_mem_alloc() vermutlich vom Wayland Compositor bereitgestellt. Auf meinem System wäre das KWin.

Hast Du ein X11-System? Dann wird  win_mem_alloc() vermutlich von X11 oder vom Video-Treiber bereitgestellt. Oder vom Compositor, falls Du einen verwendest.

ich vermute, dass win_mem_alloc() weder bei einem X11-, noch bei einem Wayland-System von Mesa bereitgestellt wird.

Also brauchen wir in Mesa auch nicht nach dem Fehler zu suchen.

Auf Deinem System: in welchem Modul / in welcher Shared Library würdest Du win_mem_alloc() vermuten?

----------

## Tyrus

@mv:

Zum Vergleich mal meine Debug-Ausgabe:

```

[..]

(gdb) run

Starting program: /home/mithrandir/helper/a 

[Thread debugging using libthread_db enabled]

Using host libthread_db library "/lib64/libthread_db.so.1".

[New Thread 0x7fffec683700 (LWP 24217)]

[New Thread 0x7fffdc6b2700 (LWP 24218)]

[Thread 0x7fffec683700 (LWP 24217) exited]

[Thread 0x7fffdc6b2700 (LWP 24218) exited]

[Inferior 1 (process 24213) exited normally]

```

Was mir erst mal auffällt ist das nur 2 Threads gestartet werden. Bei deinem Debuglauf sind es aber drei. Woher kommt der dritte Thread?

----------

## mv

Vielen Dank erstmal für die Hinweise.

Durch tiefes rebuild aller Dependencies mit den "sichersten" Settings (CFLAGS, ohne Gold) habe ich es jetzt doch geschafft, ein System aufzusetzen, bei dem mein Testprogramm läuft.

Jetzt kann ich einfach systematisch probieren, welche Dependencies die Probleme verursachten.

Es ist jetzt wohl nur eine Zeitfrage. Ich melde mich, sobald ich die Ursache gefunden habe.

Ich benutze übrigens X11 (obwohl das System mit USE=wayland aufgesetzt ist, aber da ich von gnome und kde nur wenig installiert habe, habe ich derzeit außer westen keinen compositor).

----------

## mv

Problem gelöst:

/var/tmp war bei mir ein tmpfs mit size=1m. Anscheinend benutzt qt dieses Directory und benötigt dort mehr Speicher. Mit size=10m gibt es keinen Busfehler mehr.

(Die Lösung hat gar nichts mit meiner obigen Ankündigung zu tun - die Änderung der Größe hatte ich nur zufällig parallel mit dem rebuild durchgeführt.)

----------

## Josef.95

 *mv wrote:*   

> /var/tmp war bei mir ein tmpfs [...]

 

/var/tmp in den RAM zu packen ist wahrscheinlich auch keine gute Idee. /var/tmp ist nicht dafür vorgesehen bei jedem reboot gelöscht zu werden (ich denke dafür nutzt man besser /tmp ).

(siehe zb auch im `man hier`)

----------

## mv

 *Josef.95 wrote:*   

> /var/tmp ist nicht dafür vorgesehen bei jedem reboot gelöscht zu werden

 

Ja, theoretisch. In der Praxis will man aber nur die Unterverzeichnisse ccache und ev. noch portage aufbewahren und den Rest löschen (insbesondere z.B. fonts).

Vor allem will man in der Praxis /var/tmp (da world-beschreibbar) als "noexec" mounten. Was tun, wenn man keine weitere Harddisk-Partition mehr hat?

Einfach ccache (und ggf. portage) woanders hin verlagern, /var/tmp als tmpfs, und mit tmpfiles.d beim Booten Symlinks setzen.

Hatte jahrelang geklappt.

Wer erwartet denn schon, dass qt-5.11 megabyteweise Daten in (nicht sichtbare. also vermutlich sofort beim Öffnen gelöschte) Dateien von /var/tmp schreibt?

----------

## mike155

@mv: Toll, dass Du die Ursache gefunden hast!  :Smile: 

Ist wirklich /var/tmp "an sich" das Problem? Oder ist es  XDG_CACHE_HOME, das bei Dir auf /var/tmp/... zeigt?

Jedenfalls gibt es irgendwo einen Bug: es fehlt eine Fehlerüberprüfung nach einer fehlgeschlagenen Funktion, die Ressourcen benötigt.

 *Josef.95 wrote:*   

> /var/tmp in den RAM zu packen ist wahrscheinlich auch keine gute Idee.
> 
> 

 

Hmm - das mache ich seit Jahren so. Es hat bisher nie zu Problemen geführt. 

Ich habe mal in den FHS geschaut:

 *FHS wrote:*   

> /var/tmp : Temporary files preserved between system reboots
> 
> Purpose:
> 
> The /var/tmp directory is made available for programs that require temporary files or directories that are preserved between system reboots. Therefore, data stored in /var/tmp is more persistent than data in /tmp.
> ...

 

Dieser Abschnitt ist selbst für den FHS außerordentlich vage...  :Shocked: Last edited by mike155 on Sat Nov 03, 2018 1:21 am; edited 1 time in total

----------

## mike155

 *mike155 wrote:*   

> Ist wirklich /var/tmp "an sich" das Problem? Oder ist es XDG_CACHE_HOME, das bei Dir auf /var/tmp/... zeigt? 
> 
> 

 

Ich kann den Fehler jetzt reproduzieren:

```
# als root: 

mount -t tmpfs -o size=30k tmpfs /mnt   

# als normaler User:

# XDG_CACHE_HOME zeigt auf "/tmp/..."

gdb ./a     

   run     

   # Programm läuft einwandfrei

   quit

export XDG_CACHE_HOME="/mnt" 

gdb ./a

   run   

   # Jetzt gibt es die Meldung: Thread 1 "a" received signal SIGBUS, Bus error.

```

Es ist also nicht /var/tmp "an sich", sondern  das Verzeichnis, auf das XDG_CACHE_HOME zeigt. Bei mir tritt der SIGBUS-Fehler auf, wenn das Verzeichnis kleiner ist als ca. 30 kB. Bei mehr als 100 kB tritt kein Fehler auf. 

Hier die Ausgabe von "strace -f":

```
> grep mnt /tmp/strace-log

1500  stat("/mnt", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=40, ...}) = 0

1500  stat("/mnt", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=40, ...}) = 0

1500  stat("/mnt/mesa_shader_cache", 0x7ffdf6438cc0) = -1 ENOENT (No such file or directory)

1500  mkdir("/mnt/mesa_shader_cache", 0755) = 0

1500  openat(AT_FDCWD, "/mnt/mesa_shader_cache/index", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 9

1500  mkdir("/mnt", 0777)               = -1 EEXIST (File exists)

1500  stat("/mnt", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=60, ...}) = 0

1500  openat(AT_FDCWD, "/mnt/icon-cache.kcache", O_RDWR|O_CREAT|O_CLOEXEC, 0666) = 9

```

Nach der letzten Anweisung geht es folgendermaßen weiter:

```
1500 openat(AT_FDCWD, "/mnt/icon-cache.kcache", O_RDWR|O_CREAT|O_CLOEXEC, 0666) = 9

1500 statx(9, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS, stx_attributes=0, stx_mode=S_IFREG|0640, stx_size=0, ...}) = 0

1500 lseek(9, 0, SEEK_CUR)             = 0

1500 ftruncate(9, 10547304)            = 0

1500 fallocate(9, 0, 0, 10547304)      = -1 ENOSPC (No space left on device)

1500 mmap(NULL, 10547304, PROT_READ|PROT_WRITE, MAP_SHARED, 9, 0) = 0x7f71484df000    <=== Diese Anweisung dürfte nicht passieren!. Offenbar wurde das ENOSPC nicht abgefangen!

1500  --- SIGBUS {si_signo=SIGBUS, si_code=BUS_ADRERR, si_addr=0x7f71484e3020} ---

```

Jetzt müssen wir nur noch die Stelle im Source-Code finden - und einen Bug-Report schreiben!Last edited by mike155 on Sat Nov 03, 2018 4:43 am; edited 3 times in total

----------

## Josef.95

Jo, wie auch immer - fein das ihr die Ursache gefunden habt :)

----------

## mike155

Nach langem Suchen habe ich  den Fehler gefunden. Es ist folgende Stelle:

Paket: kde-frameworks/kcoreaddons-5.51.0

Datei: src/lib/caching/kshareddatacache.cpp

Funktion: void mapSharedMemory()

Zeile 1051 ff.

```
if (file.open(QIODevice::ReadWrite) &&

    (file.size() >= size ||

     (file.resize(size) && ensureFileAllocated(file.handle(), size)))) 

```

Ich habe einen Bug bei KDE geöffnet: https://bugs.kde.org/show_bug.cgi?id=400610.

----------

## mv

Bei mir scheint es anders zu sein, vermutlich weil ich kein kde installiert habe:

Insbesondere habe ich kde-frameworks/kcoreaddons nicht installiert.

Ich habe $XDG_CACHE_HOME nicht gesetzt, aber es kann natürlich sein, dass der Default dafür /var/tmp ist.

Die einzigen XDG_* Variablen bei mir sind:

 *Quote:*   

> XDG_CONFIG_DIRS=/etc/xdg
> 
> XDG_DATA_DIRS=/usr/local/share:/usr/share
> 
> XDG_RUNTIME_DIR=/run/xdg/runtime-$USER

 

(Nur letzteres habe ich bewusst mit Hilfe von tmpfiles.d umkonfiguriert, weil mir ein vorhersagbarer Name wie runtime-$USER in /tmp suspekt erscheint - ist das nicht immer eine Sicherheitslücke in einem world-writable Directory?)

Aber ich vermute, qt kümmert sich nicht um XDG*, weil Letzteres eine reine Desktop-Angelegenheit ist.

Edit: Setzen von XDG_CACHE_HOME auf z.B. /tmp (wo es mehr Platz gibt) ändert nichts.

----------

## mike155

Ich war überrascht, dass es ein Bug in KDE ist - schließlich ist das Test-Programm ja ein reines Qt-Programm - warum sollte das einen Bug in KDE triggern?

Dann habe ich vor dem Start des Test-Programms alle Environment-Variablen gelöscht, die das Wort KDE enthalten - und siehe da - es gab keinen Fehler mehr! Allerdings hatte das sich öffnende Fenster auch keine Windows-Dekorationen mehr. Ich interpretiere das so, dass Qt zum Zeichnen der Windows-Dekorationen auf die Desktop-Umgebung zugreift. Und wenn es dort einen Fehler gibt, stürzt das Qt-Programm eben ab. Es scheint mir jedenfalls kein Bug in Qt zu sein.

@mv: welche Desktop-Umgebung verwendest Du? XFCE? Ich vermute, dass es dort einen ähnlichen Bug gibt, wie in KDE. 

Falls Du den Fehler suchen möchtest, könntest Du einen "strace -f" ziehen, dort nach "/var/tmp" suchen und Dir dann alles anschauen, was mit Objekten in diesem Verzeichnis zu tun hat. Bei mir waren es nur wenige Zeilen und ich habe den Fehler (mmap nach fehlgeschlagenen fallocate) schnell gefunden.

Viel Glück!

----------

## mv

 *mike155 wrote:*   

> @mv: welche Desktop-Umgebung verwendest Du? XFCE?

 

Keine Desktop-Umgebung; nur fvwm(-crystal). Aber mit xfce (das ich nur mal kurz zum Testen mit xfce4-meta installiert und gebootet hatte) hatte ich das selbe Ergebnis.

 *Quote:*   

> Falls Du den Fehler suchen möchtest, könntest Du einen "strace -f" ziehen, dort nach "/var/tmp" suchen

 

Das scheint nicht zu helfen:

```
% strace -f ./a 2>&1|\grep /var

[1]    3620531 bus error  strace -f ./a 2>&1 | 

       3620532 exit 1     \grep /var
```

Auf /var/tmp liegen zwei fifos von fvwm, aber m.W. schreiben fifos nicht wirklich etwas in das Dateisystem wenn sie zu voll werden. Oder vielleicht doch?

----------

## mv

Es kommt noch besser: Selbst nach chmod a-rwx /var/tmp tritt der selbe Effekt auf:

mount -o remount -o size=10m /var/tmp -> alles geht

mount -o remount -o size=1m /var/tmp -> bus error

----------

## Tyrus

Also mal ein Testlauf bei mir.

Als Root:

```

mount -t tmpfs -o size=30k tmpfs /mnt/cdrom/

```

dann als normaler User:

```

mithrandir@luthien ~ $ export XDG_CACHE_HOME="/mnt/cdrom"

mithrandir@luthien ~ $ echo $XDG_CACHE_HOME

/mnt/cdrom

mithrandir@luthien ~ $ cd helper

mithrandir@luthien ~/helper $ ./a 

KCrash: Application 'a' crashing...

KCrash: Attempting to start /usr/lib64/libexec/drkonqi from kdeinit

sock_file=/var/run/user/1000/kdeinit5__0

[1]+  Angehalten              ./a

mithrandir@luthien ~/helper $ QSocketNotifier: Invalid socket 8 and type 'Read', disabling...

QSocketNotifier: Invalid socket 9 and type 'Read', disabling...

[1]+  Angehalten              ./a

```

Anmerken möchte ich das XDG_CACHE_HOME vor dem Export nicht gesetzt war.

Jetzt die Ausgabe von KCrash:

```

Application: a (a), signal: Bus error

Using host libthread_db library "/lib64/libthread_db.so.1".

28     return SYSCALL_CANCEL (nanosleep, requested_time, remaining);

[Current thread is 1 (Thread 0x7f3bccb5fbc0 (LWP 11715))]

Thread 3 (Thread 0x7f3bb12e1700 (LWP 11717)):

#0  0x00007f3bc89377e9 in g_mutex_lock () from /usr/lib64/libglib-2.0.so.0

#1  0x00007f3bc88f1652 in g_main_context_query () from /usr/lib64/libglib-2.0.so.0

#2  0x00007f3bc88f1e77 in g_main_context_iterate.isra () from /usr/lib64/libglib-2.0.so.0

#3  0x00007f3bc88f200c in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0

#4  0x00007f3bcb65f44b in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5

#5  0x00007f3bcb60b43a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5

#6  0x00007f3bcb46daea in QThread::exec() () from /usr/lib64/libQt5Core.so.5

#7  0x00007f3bc41f1de5 in QDBusConnectionManager::run() () from /usr/lib64/libQt5DBus.so.5

#8  0x00007f3bcb47754f in QThreadPrivate::start(void*) () from /usr/lib64/libQt5Core.so.5

#9  0x00007f3bcaf1496a in start_thread (arg=0x7f3bb12e1700) at pthread_create.c:463

#10 0x00007f3bca29f91f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 2 (Thread 0x7f3bc1264700 (LWP 11716)):

#0  0x00007f3bca293d43 in __GI___poll (fds=0x7f3bc1263d28, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29

#1  0x00007f3bc57187f7 in _xcb_conn_wait () from /usr/lib64/libxcb.so.1

#2  0x00007f3bc571a42a in xcb_wait_for_event () from /usr/lib64/libxcb.so.1

#3  0x00007f3bc46f17a9 in QXcbEventReader::run() () from /usr/lib64/libQt5XcbQpa.so.5

#4  0x00007f3bcb47754f in QThreadPrivate::start(void*) () from /usr/lib64/libQt5Core.so.5

#5  0x00007f3bcaf1496a in start_thread (arg=0x7f3bc1264700) at pthread_create.c:463

#6  0x00007f3bca29f91f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7f3bccb5fbc0 (LWP 11715)):

[KCrash Handler]

#6  0x00007f3bb92119c2 in SharedMemory::clearInternalTables() () from /usr/lib64/libKF5CoreAddons.so.5

#7  0x00007f3bb9215a3c in KSharedDataCache::Private::mapSharedMemory() () from /usr/lib64/libKF5CoreAddons.so.5

#8  0x00007f3bb920d4a5 in KSharedDataCache::KSharedDataCache(QString const&, unsigned int, unsigned int) () from /usr/lib64/libKF5CoreAddons.so.5

#9  0x00007f3bba5342ef in KIconLoaderPrivate::init(QString const&, QStringList const&) () from /usr/lib64/libKF5IconThemes.so.5

#10 0x00007f3bba53496b in KIconLoader::KIconLoader(QString const&, QStringList const&, QObject*) () from /usr/lib64/libKF5IconThemes.so.5

#11 0x00007f3bba534cc3 in KIconLoader::global() () from /usr/lib64/libKF5IconThemes.so.5

#12 0x00007f3bbbdc0655 in KHintsSettings::setupIconLoader() () from /usr/lib64/qt5/plugins/platformthemes/KDEPlasmaPlatformTheme.so

#13 0x00007f3bcb63688a in QObject::event(QEvent*) () from /usr/lib64/libQt5Core.so.5

#14 0x00007f3bcc2bbd8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5

#15 0x00007f3bcc2c334f in QApplication::notify(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5

#16 0x00007f3bcb60c647 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib64/libQt5Core.so.5

#17 0x00007f3bcb60f4a1 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib64/libQt5Core.so.5

#18 0x00007f3bcb65f643 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/lib64/libQt5Core.so.5

#19 0x00007f3bc88f1bd7 in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0

#20 0x00007f3bc88f1f80 in g_main_context_iterate.isra () from /usr/lib64/libglib-2.0.so.0

#21 0x00007f3bc88f200c in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0

#22 0x00007f3bcb65f42f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5

#23 0x00007f3bc477a731 in QPAEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5XcbQpa.so.5

#24 0x00007f3bcb60b43a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5

#25 0x00007f3bcb613e20 in QCoreApplication::exec() () from /usr/lib64/libQt5Core.so.5

#26 0x000055fceeef5c08 in main ()

```

Sieht so aus als ob mike155 nahe dran ist an der Stelle. Aber es ist nicht die Funktion void mapSharedMemory(), sondern wenn ich das richtig lese und verstehe kommt noch der Aufruf SharedMemory::clearInternalTables().

Der Aufruf von QObject::event(QEvent*) in /usr/lib64/libQt5Core.so.5 scheint die Funktion zu sein nach der KDE-Bibliotheken die Ausführung des Codes übernehmen. Inwieweit das bei einer anderen Umgebung als KDE dann zum Fehler führt müsste man mal testen.

Edit:

Was auffällt Qt springt aber auch drauf an. Also genauer der QSocketNotifer meldet zweimal ein Invalid Socket bei mir. 

Die Dokumentation dazu schreibt folgendes:

 *Quote:*   

> 
> 
> The QSocketNotifier class provides support for monitoring activity on a file descriptor.
> 
> The QSocketNotifier makes it possible to integrate Qt's event loop with other event loops based on file descriptors. File descriptor action is detected in Qt's main event loop (QCoreApplication::exec()).
> ...

 

----------

## mike155

@Tyrus: Schön, dass Du den KDE Fehler reproduzieren kannst. Ich hoffe, dass die KDE Entwickler dies auch können - und dass sie den Bug beheben werden. Ich habe noch etwas gesucht und einen KDE Bug-Report von vor 4 Jahren gefunden, der offenbar das gleiche Problem beschreibt - allerdings ohne die genaue Stelle zu benennen.

Deine und meine Beobachtungen passen sehr gut zusammen. Ich  glaube, dass ich die richtige Stelle gefunden habe und in meinem Bug-Report gemeldet habe. Der Fehler passiert früher, als der SIGBUS Crash:

In der Funktion mapSharedMemory() soll ein ins Memory gemappter Cache angelegt werden. Dies scheitert, weil kein Plattenplatz vorhanden ist. Im strace sieht man folgendes:

```
1500 openat(AT_FDCWD, "/mnt/icon-cache.kcache", O_RDWR|O_CREAT|O_CLOEXEC, 0666) = 9

1500 statx(9, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS, stx_attributes=0, stx_mode=S_IFREG|0640, stx_size=0, ...}) = 0

1500 lseek(9, 0, SEEK_CUR)             = 0

1500 ftruncate(9, 10547304)            = 0

1500 fallocate(9, 0, 0, 10547304)      = -1 ENOSPC (No space left on device)        <=== Fallocate scheitert wegen Platzmangel

1500 mmap(NULL, 10547304, PROT_READ|PROT_WRITE, MAP_SHARED, 9, 0) = 0x7f71484df000  <=== Anstelle von mmap() hätte eine Fehlermeldung und ein abort() erfolgen müssen

```

Im Ergebnis gibt es jetzt einen fehlerhaft gemappten Speicherbereich im Memory. Sobald man darauf zugreift, wird es einen Fehler geben. Da aber in mapSharedMemory() noch nicht zugegriffen wird, läuft das Programm erst einmal weiter.

Der Zugriff auf den fehlerhaft gemappten Speicherbereich erfolgt laut Deiner Ausgabe von KCrash in SharedMemory::clearInternalTables. Jetzt erst gibt es den SIGBUS Crash. Der eigentliche Fehler ist aber, dass der Fehler-Rückgabecode von fallocate() in mapSharedMemory() nicht abgefangen wurde.

----------

## Tyrus

@mike155:

Jop, danke. Ich stimme dir zu was deine Erklärung angeht.

----------

## mike155

Zu meiner großen Freude haben die KDE-Entwickler schon einen Bug-Fix entwickelt: https://phabricator.kde.org/D16744. 

In Zukunft soll eine aussagekräftige Meldung generiert werden:

 *Quote:*   

> No space left on device. Check filesystem free space at your XDG_CACHE_HOME!
> 
> The operating system is unable to promise 10547304 bytes for mapped cache, abandoning the cache for crash-safety.
> 
> org.kde.kcoreaddons: Failed to establish shared memory mapping, will fallback to private memory -- memory usage will increase
> ...

 

Das ist das, was ich an der Open-Source Community so liebe: mehrere Entwickler, die sich noch nicht einmal kennen,  arbeiten zusammen - und am Ende wird die Software besser...  :Smile: 

Leider hilft der Bug-Fix für KDE noch nicht mv, der das Problem ursprünglich gepostet hat. Hoffentlich finden wir auch für seine Konfiguration noch die Fehlerursache!

----------

## mike155

Heute habe ich versucht, dass Problem von mv unter fvwm zu reproduzieren. Ich habe...

das Paket 'fvwm' installiert (emerge fvwm)

'exec fvwm' nach ~/.xinitrc geschrieben

die GUI mit 'startx' gestartet

Der von mv beschriebene Fehler tritt auch bei mir auf. Wenn '/var/tmp' 1 MB oder kleiner ist, erhalte ich einen Bus error.

Bisher habe ich folgendes herausgefunden:

Es hängt NICHT mit fvwm zusammen. Der Fehler tritt auch auf, wenn ich lediglich 'exec /usr/bin/xterm' nach ~/.xinitrc schreibe - also fvwm gar nicht verwende.

Wie mv schon geschrieben hat: im strace-Log findet man keine Systemaufrufe zu "/var/tmp". Außerdem zeigt ein "ls /var/tmp" weder nach einem abgestürzten Lauf von a, noch während eines laufendes Aufrufs von a (bei größerem /var/tmp) Dateien in /var/tmp.

Mit lsof findet man bei einer laufenden Instanz von a sehr wohl Objekte in /var/tmp:

```
> lsof | grep "/var/tmp/"

Xorg  24386                         root  DEL  REG  0,45  250338 /var/tmp/#250338

Xorg  24386 24389 InputThre         root  DEL  REG  0,45  250338 /var/tmp/#250338

a     24803                   <username>  DEL  REG  0,45  250338 /var/tmp/#250338

a     24803 24804 QXcbEvent   <username>  DEL  REG  0,45  250338 /var/tmp/#250338

a     24803 24805 a:disk$0    <username>  DEL  REG  0,45  250338 /var/tmp/#250338

a     24803 24806 QDBusConn   <username>  DEL  REG  0,45  250338 /var/tmp/#250338

```

Es finden also Operation auf /var/tmp statt. Als nächstes müssen wir herausfinden, wer für diese Objekte verantwortlich ist und warum es zum dem SIGBUS kommt.

Ich habe mir den strace noch einmal genauer angesehen. Die spannenden Zeilen sind:

```
24747 mmap(NULL, 1228800, PROT_READ|PROT_WRITE, MAP_SHARED, 9, 0) = 0x7fcfec534000

24747 close(9) = 0

24747 --- SIGBUS {si_signo=SIGBUS, si_code=BUS_ADRERR, si_addr=0x7fcfec62e000} ---
```

9 ist ein File-Descriptor. Auf den wird mmap() ausgeführt und sobald das Programm auf den Speicherbereich zugreift, hagelt es einen Bus error. Das kommt mir sehr bekannt vor: exakt das Gleiche, wie bei dem KDE-Bug weiter oben! Vermutung: fd=9 gehört zu einem Objekt in /var/tmp. Jetzt müssen wir herausfinden, wer das Objekt mit fd=9 anlegt. In unserem Test-Programm 'a' und in aufgerufenen Bibliotheken passiert das nicht - das würde man im strace Log sehen. Also wird es ein nicht zu 'a' gehörender Prozess sein - und der File-Descriptor wird über einen IPC-Mechanismus übergeben. Jetzt wird es spannend!

Der nicht funktionierende mmap()-Aufruf steht im Paket dev-qt/qtgui, in der Datei: src/plugins/platforms/xcb/qxcbbackingstore.cpp, Zeile 370:

```
void *addr = mmap(nullptr, segmentSize, PROT_READ|PROT_WRITE, MAP_SHARED, fds[0], 0);

```

Offenbar prüfen weder Qt, noch XCB, ob genügend Platz zur Verfügung steht.

----------

## mike155

Ich habe einen Bug Report bei den Qt Entwicklern eingestellt: https://bugreports.qt.io/browse/QTQAINFRA-2381. 

Das Problem ist vermutlich nicht einfach zu lösen, weil sowohl Xcb, als auch Qt beteiligt sind. Hoffentlich werden die Entwickler eine einfache Lösung finden.

Anmerkung am 14.12.2018:

Der Link zum Bug hat sich geändert auf: https://bugreports.qt.io/browse/QTBUG-72535Last edited by mike155 on Fri Dec 14, 2018 4:44 pm; edited 1 time in total

----------

## mv

Vielen Dank für Deine Mühe (Untersuchung der Ursache und Anlegen des Bugreports)

----------

## mike155

Während die KDE Entwickler ihren Bug innerhalb weniger Tage gefixt haben, gibt es bei Qt noch keine Lösung. Einige Qt Entwickler sind der Meinung, dass es an einem falsch übersetzten X-Server unter Gentoo Linux liegt ("In short, the X server should be built with --with-shared-memory-dir=/dev/shm"). Das mag sein, aber ich fände es schön, wenn in Qt trotzdem überprüft würde, ob mit mmap() angeforderter Speicher tatsächlich zur Verfügung steht.

----------

