strace/ptrace 会导致程序崩溃吗?

strace/ptrace 会导致程序崩溃吗?

最近,我正在与某人讨论 strace,他们问如果你在创建网络套接字或类似的东西时对正在运行的进程进行 strace 会发生什么。这会导致程序以意想不到的方式崩溃吗?

根据我读到的关于 ptrace(strace 使用的系统调用)的内容,如果您只是调试线程,它不应该导致类似的情况。每次调用系统调用时,该进程都会停止,但稍后应该会恢复并且不会变得更明智。信号在不运行时排队,所以我假设系统调用/套接字/监听也会发生类似的情况。

在 strace 上下文中使用 ptrace 会导致任何奇怪的进程崩溃吗?

答案1

strace不应导致程序崩溃 -

除了在这个有点不寻常的情况下:

如果它有一个依赖于执行时间,或运行时记忆位置

可能会引发这种“海森巴格“ - 但极其罕见,因为这种 bug 很少见,它只需要在 strace 或其他仪器下触发。当你发现 heisenbug 时,这通常是一件好事。

关于ptrace()系统调用,这正是strace我所认为的,所以它是相似的。人们可以比直接strace使用时做更多的事情ptrace()


你的例子就是这种错误:

在示例中,strace将更改创建网络连接的步骤的时间安排。如果这导致了问题,那么它就是一个“等待发生的问题”——执行的时间不断变化。有了strace,就多一点。但任何其他应用程序都可以更多地改变时间,例如启动程序。

答案2

如果您在创建网络套接字或类似内容时跟踪正在运行的进程,会发生什么。

类似的事情是通过完成的系统调用,意味着进程向内核发出请求,内核会满足它。内核还具有使ptrace()工作正常进行的魔力。虽然这并不意味着它不可能被自身绊倒(这将是一个错误),但这似乎不太可能,因为这明确是其目的之一:协调多任务系统上的进程。

答案3

我发现跟踪 GUI 进程经常会导致崩溃,即使在最近的操作系统上也是如此(至少是 OpenSuse 12.3,我没有专门尝试过 13.1,因为我几乎放弃了跟踪 GUI 进程)。

我不记得在任何最近的操作系统上看到非 GUI 进程的跟踪导致崩溃。

答案4

是的。这种情况很少见,我也不知道为什么,但它肯定会发生。最近,我在跟踪长时间运行的“swapoff”命令时遇到了这种情况,并且没有网络访问权限,也没有其他任何看起来会/应该导致问题的东西。尽管如此,在附加 strace 后不久,该进程就退出了。

>strace -p 73358
strace: Process 73358 attached
getuid()                                = 0
geteuid()                               = 0
getgid()                                = 0
getegid()                               = 0
prctl(PR_GET_DUMPABLE)                  = 1
stat("/etc/fstab", {st_mode=S_IFREG|0644, st_size=2168, ...}) = 0
open("/etc/fstab", O_RDONLY|O_CLOEXEC)  = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2168, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f24e5cd8000
read(3, "\n#\n# /etc/fstab\n# Created by ana"..., 4096) = 2168
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7f24e5cd8000, 4096)            = 0
close(1)                                = 0
close(2)                                = 0
exit_group(-1)                          = ?
+++ exited with 255 +++

看起来进程决定自动退出,但考虑到在 strace 开始之前它已经运行了几个小时,我怀疑这次退出是巧合。

所以,是的,strace 有时会导致进程中止,但获得良好信息的好处超过风险的情况非常罕见。

Linux 上的另一个选择是检查/proc/<PID>/stack进程当前被阻止的位置。这更安全,但提供的动态信息较少。

相关内容