我正在尝试调试缩略图生成过程中的特殊性能行为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 会触发此行为。然而,eog
仅仅gdk-pixbuf-thumbnailer
在 SVG 上运行是不够的。此行为仅在以下情况下发生:
eog
在目录上运行;目录中有一个特定的 SVG,该 SVG 中还没有缩略图
~/.cache/thumbnails/
。(我用来
touch
更新 SVG 的时间戳并让缩略图每次重新运行。)同一目录中至少有一张其他图像;
另一个图像的文件名是整理的前SVG 文件名。
(如果文件名整理后SVG 文件名,它会在不到一秒的时间内生成缩略图。否则大约需要 30 秒。)
还有一些其他的谜题。在里面strace
日志,挂钟时间似乎与系统调用所花费的时间不匹配。我曾在旗帜eog
下奔跑:strace
-f
-f
跟踪当前跟踪的进程由于 fork(2)、vfork(2) 和clone(2) 系统调用而创建的子进程。
我也尝试过该-ff
标志:
-ff
如果该
-o filename
选项有效,则每个进程跟踪都会写入 每个进程的数字进程 ID 中filename.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
进程并查看它花费时间在哪个函数上?什么可能导致这种行为?
答案1
在找到正确的网络搜索关键字组合后,我 90% 确定这是 2018 年 12 月 15 日的此错误的重复:
由于字体问题,缩略图生成速度缓慢
因此,我正在调查自动重新加载 SVG 文件时 eog 速度下降的情况,问题似乎出在缩略图生成上,大约需要 10 秒。 (请注意,对于一个很小的 SVG。)更具体地说,
gdk-pixbuf-thumbnailer
抱怨找不到字体配置并花了很多时间查看字体。添加--ro-bind /var/cache/fontconfig /var/cache/fontconfig
bwrap 的参数解决了问题,时间降至约 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
。
缩略图:修复由于缺少字体缓存而导致缩略图速度缓慢的问题
在某些发行版上,字体缓存并不位于 /usr 中,而是位于 /var 中,在对缩略图进行沙箱处理时,我们不允许访问 /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