Fonts

調試緩慢的縮略圖程序

  • July 25, 2019

我正在嘗試在縮略圖生成過程中調試一種特殊的性能行為eog,特別是gdk-pixbuf. 要重現的最小文件在這裡:

https://github.com/nbeaver/gdk-pixbuf-bug

程序樹如下所示:

systemd,1 splash
 `-plasmashell,4366
     `-konsole,6783
         `-bash,6793
             `-make,6949 reproduce
                 `-eog,6973 /usr/share/doc/docutils-doc/docs/user/images
                     `-bwrap,10071 --ro-bind /usr /usr --ro-bind /bin /bin --ro-bind /lib64 /lib64 --ro-bind /lib /lib --ro-bind /sbin /sbin --proc /proc --dev /dev --chdir / --setenv GIO_USE_VFS local --unshare-all --die-with-parent --bind /tmp/gnome-desktop-thumbnailer-2HUN5Z /tmp --ro-bind /usr/share/doc/docutils-doc/docs/user/images/s5-files.svg /tmp/gnome-desktop-file-to-thumbnail.svg --seccomp 11 /usr/bin/gdk-pixbuf-thumbnailer -s 128 file:///tmp/gnome-desktop-file-to-thumbnail.svg /tmp/gnome-desktop-thumbnailer.png
                         `-bwrap,10074 --ro-bind /usr /usr --ro-bind /bin /bin --ro-bind /lib64 /lib64 --ro-bind /lib /lib --ro-bind /sbin /sbin --proc /proc --dev /dev --chdir / --setenv GIO_USE_VFS local --unshare-all --die-with-parent --bind /tmp/gnome-desktop-thumbnailer-2HUN5Z /tmp --ro-bind /usr/share/doc/docutils-doc/docs/user/images/s5-files.svg /tmp/gnome-desktop-file-to-thumbnail.svg --seccomp 11 /usr/bin/gdk-pixbuf-thumbnailer -s 128 file:///tmp/gnome-desktop-file-to-thumbnail.svg /tmp/gnome-desktop-thumbnailer.png
                             `-gdk-pixbuf-thum,10075 -s 128 file:///tmp/gnome-desktop-file-to-thumbnail.svg /tmp/gnome-desktop-thumbnailer.png

strace日誌中,看起來/usr/bin/gdk-pixbuf-thumbnailer大約需要 30 秒查看字型檔:

22:44:05 munmap(0x7fd491988000, 20930832) = 0 <0.000558>
22:44:05 openat(AT_FDCWD, "/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", O_RDONLY) = 5 <0.000060>
22:44:05 fcntl(5, F_SETFD, FD_CLOEXEC)  = 0 <0.000014>
22:44:05 fstat(5, {st_mode=S_IFREG|0644, st_size=20930832, ...}) = 0 <0.000013>
22:44:05 mmap(NULL, 20930832, PROT_READ, MAP_PRIVATE, 5, 0) = 0x7fd491988000 <0.000021>
22:44:05 close(5)                       = 0 <0.000011>
22:44:06 munmap(0x7fd491988000, 20930832) = 0 <0.000525>
22:44:06 openat(AT_FDCWD, "/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", O_RDONLY) = 5 <0.000076>
22:44:06 fcntl(5, F_SETFD, FD_CLOEXEC)  = 0 <0.000013>
22:44:06 fstat(5, {st_mode=S_IFREG|0644, st_size=20930832, ...}) = 0 <0.000012>
22:44:06 mmap(NULL, 20930832, PROT_READ, MAP_PRIVATE, 5, 0) = 0x7fd491988000 <0.000023>
22:44:06 close(5)                       = 0 <0.000013>
<snip>
22:44:31 stat("/usr/share/fonts/opentype/stix-word/STIXMath-Regular.otf", {st_mode=S_IFREG|0644, st_size=476872, ...}) = 0 <0.000024>
22:44:31 openat(AT_FDCWD, "/usr/share/fonts/opentype/stix-word/STIXMath-Regular.otf", O_RDONLY) = 5 <0.000026>
22:44:31 fcntl(5, F_SETFD, FD_CLOEXEC)  = 0 <0.000014>
22:44:31 fstat(5, {st_mode=S_IFREG|0644, st_size=476872, ...}) = 0 <0.000013>
22:44:31 mmap(NULL, 476872, PROT_READ, MAP_PRIVATE, 5, 0) = 0x7fd49c26a000 <0.000023>
22:44:31 close(5)                       = 0 <0.000015>

有一個特定的 SVG 會觸發此行為。但是,僅在 SVG 上執行eog 或執行是不夠的。gdk-pixbuf-thumbnailer此行為僅在以下情況下發生:

  • 在目錄上執行eog
  • 目錄中有一個特定的 SVG,但~/.cache/thumbnails/.

(我touch用來更新 SVG 的時間戳並讓縮略圖每次都再次執行。)

  • 在同一目錄中至少有一個其他圖像;
  • 另一個圖像的文件名在 SVG 文件名之前進行整理。

(如果文件名在 SVG 文件名之後排序,它會在不到一秒的時間內生成縮略圖。否則大約需要 30 秒。)

還有一些其他的謎題。在strace日誌中,掛鐘時間似乎與系統呼叫所花費的時間不匹配。我已經在旗幟eog下奔跑:strace``-f

-f

由於 fork(2)、vfork(2) 和 clone(2) 系統呼叫由目前跟踪的程序創建,因此跟踪子程序。

我也嘗試過這個-ff標誌:

-ff

如果該-o filename選項有效,則每個程序跟踪都將寫入每個程序 的數字程序 IDfilename.pid所在的位置。pid

但在任何一種情況下 gdk-pixbuf-thumbnailer都不會出現在子程序的日誌文件中。

我也無法執行(gdb關於gdk-pixbuf-thumbnailer “目標和調試器位於不同的 PID 命名空間”),所以我不知道它卡在哪裡了。

$ sudo gdb -p 20789
[sudo] password for nathaniel:
<snip>
Error while mapping shared library sections:
Could not open `target:/lib/x86_64-linux-gnu/libbsd.so.0' as an executable file: No such file or directory

warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.

warning: Target and debugger are in different PID namespaces; thread lists and other data are likely unreliable.  Connect to gdbserver inside the container.
(gdb) quit
Detaching from program: target:/newroot/usr/bin/gdk-pixbuf-thumbnailer, process 20789

我猜這與bwrap容器有關。

版本資訊:

$ apt-cache policy libgdk-pixbuf2.0-bin eog
libgdk-pixbuf2.0-bin:
 Installed: 2.36.11-2
 Candidate: 2.36.11-2
 Version table:
*** 2.36.11-2 500
       500 http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages
       100 /var/lib/dpkg/status
eog:
 Installed: 3.28.1-1
 Candidate: 3.28.1-1
 Version table:
*** 3.28.1-1 500
       500 http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages
       100 /var/lib/dpkg/status

我的問題是:

  • 這個錯誤可以在其他機器和其他版本上重現嗎?

(我碰巧使用的是 Ubuntu 18.04,但我想知道這是否發生在其他發行版上。)

  • 為什麼不 作為子程序strace -f拾取?/usr/bin/gdk-pixbuf-thumbnailer``eog

是否eog使用不尋常的方法來創建子程序?

  • 如何使用gdb附加到 /usr/bin/gdk-pixbuf-thumbnailer流程並查看它花費時間的功能?
  • 什麼可能導致這種行為?

在找到正確的網路搜尋關鍵字組合後,我 90% 確定這是 2018 年 12 月 15 日此錯誤的重複:

由於字型問題,縮略圖生成緩慢

因此,我正在調查自動重新載入 SVG 文件時 eog 的減速,似乎問題出在縮略圖生成中,這需要大約 10 秒。(對於一個小的 SVG,請注意。)更具體地說,gdk-pixbuf-thumbnailer 抱怨找不到字型配置並花了很多時間查看字型。添加--ro-bind /var/cache/fontconfig /var/cache/fontconfigbwrap 的參數解決了這個問題,時間減少到 ~0.2 秒。

https://gitlab.gnome.org/GNOME/gnome-desktop/issues/90

這裡提到:

…而且我們的速度也大幅放緩,請參閱 https://gitlab.gnome.org/GNOME/gnome-desktop/issues/90

https://bugs.launchpad.net/ubuntu/+source/gnome-desktop3/+bug/1795668

修復是gnome-desktop3.

thumbnail:修復了由於缺少字型記憶體而導致的慢速縮略圖

在某些發行版中,字型記憶體並不存在於 /usr 中,而是存在於 /var 中,我們不允許在沙箱化縮略圖時訪問它。如果 fontconfig 記憶體目錄位於 /usr 之外,則以只讀方式綁定掛載,以加快縮略圖啟動。

https://gitlab.gnome.org/GNOME/gnome-desktop/merge_requests/25/diffs

看起來修復是在 gnome-desktop3 版本 3.30 及更高版本中,所以截至 2019 年 7 月 19 日,只有 Ubuntu 19.10(Eoan Ermine,未發布)和 19.04(Disco Dingo,2020 年 1 月生命週期結束)。

https://launchpad.net/ubuntu/+source/gnome-desktop3

https://launchpad.net/ubuntu/+source/gnome-desktop3/+publishinghistory

我的機器的版本資訊:

$ apt-cache policy libgnome-desktop-3-17
libgnome-desktop-3-17:
 Installed: 3.28.2-0ubuntu1.5
 Candidate: 3.28.2-0ubuntu1.5
 Version table:
*** 3.28.2-0ubuntu1.5 500
       500 http://us.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages
       100 /var/lib/dpkg/status
    3.28.2-0ubuntu1.3 500
       500 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages
    3.28.1-1ubuntu1 500
       500 http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages

引用自:https://unix.stackexchange.com/questions/532011