调试缓慢的缩略图进程

调试缓慢的缩略图进程

我正在尝试调试缩略图生成过程中的特殊性能行为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.pidpid

但在任何一种情况下 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-thumbnailereog

    是否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/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

缩略图:修复由于缺少字体缓存而导致缩略图速度缓慢的问题

在某些发行版上,字体缓存并不位于 /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

相关内容