【问题标题】:What could make a program behaves differently inside `strace`?什么可以使程序在 `strace` 中表现不同?
【发布时间】:2018-12-03 16:53:59
【问题描述】:

这与https://unix.stackexchange.com/q/485682/40697 有关,但我决定采用更面向开发人员的方法。

由于某种原因,通过蓝牙串行控制台登录时,我无法在我的系统上安装软件包:

# dpkg -i /var/cache/apt/archives/openssh-server_1%3a7.4p1-10+deb9u4_armhf.deb 
dpkg: unrecoverable fatal error, aborting:
 wait for subprocess dpkg-split failed: No child processes

我尝试使用strace 追溯问题。然而:

# strace -e trace=fork dpkg -i /var/cache/apt/archives/openssh-server_1%3a7.4p1-10+deb9u4_armhf.deb
[...]
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7046, si_uid=0, si_status=0, si_utime=0, si_stime=1} ---
+++ exited with 0 +++

如您所见,在strace 内运行时,进程以退出状态 0 完成(并且包已安装)。但是在strace 之外工作时,dpkg 会系统性地失败。

FWIW,当在 gdb 内运行时,进程也会失败:

# gdb /usr/bin/dpkg
(gdb) run -i /var/cache/apt/archives/openssh-server_1%3a7.4p1-10+deb9u4_armhf.deb 
Starting program: /usr/bin/dpkg -i /var/cache/apt/archives/openssh-server_1%3a7.4p1-10+deb9u4_armhf.deb
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
dpkg: unrecoverable fatal error, aborting:
 wait for subprocess dpkg-split failed: No child processes


现在我的问题是:什么可以解释 dpkg 程序在 strace 内部运行时表现不同?

【问题讨论】:

  • 时机,一个人
  • @tink 这不是很明显,因为显然问题是由从dpkg 派生的子进程引起的。我会尝试进入子进程(如果 gdb 可以这样做?)
  • @hek2mgl 使用strace -f,我可以追踪(可能)错误的系统调用。但在strace 中它不会失败。在gdb 中,使用set follow-fork-mode 我可以跟踪到同一个呼叫,但是当我走到这一点时,我会暂停1 秒然后消息process 24043 is executing new program: /usr/bin/dpkg-split [Inferior 2 (process 24043) exited with code 01] dpkg: unrecoverable fatal error, aborting: wait for subprocess dpkg-split failed: No child processes
  • 有趣。请让我们在这里保持最新! :)
  • 我越来越确信某处存在竞争条件。如果我有任何发现,我会及时通知您。

标签: linux debian strace


【解决方案1】:

我记得之前网上已经讨论过这个了:)

https://github.com/strace/strace/issues/14

基本上你可以创建一个包装脚本,像这样(作为根):

dpkg_path="$(which dpkg)"
mv -v "${dpkg_path}" /usr/bin/dpkg-orig

> "{dpkg_path}" cat << 'EOF'
#!/bin/bash
# pro-tip: You could use a slow disk or an old usb stick
# if writes to /dev/null turn out to be too fast
exec strace -e trace=none -e signal=none -qq -o /dev/null /usr/bin/dpkg-orig "${@}"
EOF

chmod +x "${dpkg_path}"

dpkg 现在应该可以在您的系统上运行了。

【讨论】:

  • 大声笑。我已经为此编写了一个函数;)但这并不能解决从strace运行时知道为什么/如何工作不同的问题。
  • 我写这篇文章的时候不是很认真,但我认为它属于这里! :) 我喜欢那些与 strace 一起工作的错误报告!我记得互联网上有一个人称它为 strace 的药用。我最好的猜测也是时机。当进程使用 strace 运行时,某些事情需要更长的时间。这可能会产生影响,尤其是在比赛条件方面。
  • PS: ...好吧,我很惊讶当你用 gdb 运行它时会发生错误。
  • 添加了关于strace的药用的讨论链接:)
猜你喜欢
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-13
  • 2013-07-14
相关资源
最近更新 更多