Strace 守护进程开始使用服务

Strace daemon process started using service

Strace 可以通过为进程传递命令来用于跟踪进程,如下所示

strace -f -tt -o strace.log -D <SOME_COMMAND>

但是下面的命令无法跟踪启动守护进程的系统调用

strace -f -tt -o strace.log -D service nginx start

在这种情况下,strace 仅跟踪 /usr/sbin/service 的系统调用并终止。它不会跟踪由于 service nginx start

而启动的 nginx 进程上的系统调用

如何跟踪 /usr/sbin/service 启动的进程?专门寻找仅使用守护进程的解决方案!

而不是 运行 从服务中调用 nginx。 运行 service nginx stop 然后 运行

strace nginx -g "daemon off;"

这将确保您获得过程的踪迹。 -g "daemon off;" 将确保 nginx 不是 运行 作为守护进程,否则 strace 将再次结束

服务命令只是激活一个进程,如果你想strace最好直接启动进程。

如果您仍然对调试使用服务命令启动的进程感兴趣。然后执行以下操作

service nginx start
ps aux | grep nginx

从 nginx 进程中捕获 pid,然后使用

附加到它
strace -p <pid>

分叉进程

要跟踪哪一个 fork 的进程,您需要使用 -f 标志

strace -f nginx

服务跟踪

当您调用 service start nginx 时,假设系统使用 systemd,调用将转换为 systemctl start nginx。现在,如果您查看 systemd

的源代码

https://github.com/systemd/systemd/blob/cf45dd36282368d5cdf757cac2cf1fc2b562dab2/src/systemctl/systemctl.c#L3100

r = sd_bus_call_method_async(
    bus,
    NULL,
    "org.freedesktop.systemd1",
    "/org/freedesktop/systemd1",
    "org.freedesktop.systemd1.Manager",
    "Subscribe",
    NULL, NULL,
    NULL);

它没有 spawn/fork 这个过程。它将消息发送到 systemd 服务,然后启动 nginx 进程。

所以简而言之,你不能通过你的service nginx start命令进行跟踪。

更改服务的 ExecStart 属性 以包含 "strace"。例如(在 Debian Buster 上测试):

# grep ExecStart /lib/systemd/system/nginx.service
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
# cd /etc/systemd/system/
# mkdir nginx.service.d
# cat > nginx.service.d/strace.conf <<-EOD
    [Service]
    ExecStart=
    ExecStart=/usr/bin/strace -f -tt -o /tmp/strace.log -D /usr/sbin/nginx -g 'daemon on; master_process on;'
EOD
# systemctl daemon-reload
# systemctl restart nginx.service