【发布时间】:2021-01-13 16:09:58
【问题描述】:
macOS 上的一个身份不明的进程会定期在我的“下载”文件夹中创建一个空的临时文件,但以后不会将其删除
我设法找出直接的罪魁祸首是mktemp,但我想了解哪个进程调用它
我认为我可以使用$ lldb > process attach -name mktemp -watifor 在启动时附加到 mktemp,但不知道如何知道是谁首先调用它
不管有没有lldb,有什么办法知道吗?
【问题讨论】:
macOS 上的一个身份不明的进程会定期在我的“下载”文件夹中创建一个空的临时文件,但以后不会将其删除
我设法找出直接的罪魁祸首是mktemp,但我想了解哪个进程调用它
我认为我可以使用$ lldb > process attach -name mktemp -watifor 在启动时附加到 mktemp,但不知道如何知道是谁首先调用它
不管有没有lldb,有什么办法知道吗?
【问题讨论】:
这实际上比你想象的要复杂一些。
您可以通过终端运行ps -j <PID> 轻松找到 macOS 上给定进程的父进程。父 pid 是输出中的第三列。或者 Activity Monitor 有一个分层显示,以图形方式显示这些关系。
lldb 在附加时打印它附加到的进程的 pid,或者您可以在 lldb 命令target list 的输出中找到它。所以很容易找到...
但是,由于技术原因,当调试器附加到一个进程时,该进程会被内核“重新定位”到调试器。因此,如果您询问在 lldb 下运行的进程其父进程是谁,答案将始终是“debugserver”——即 lldb 的调试器存根。并且没有一种简单的方法可以查看原始父级是什么。
我得到了这个工作,虽然这有点小技巧。你想暂停你正在调试的进程,这样它就不会在你身上退出,然后与它分离,这样它就会重新回到真正的父级。所以:
(lldb) expr (void) task_suspend((void *)mach_task_self())
由于在返回之前暂停了任务,因此该命令实际上不会完成。所以
在 lldb 控制台中使用 ^C 来中断表达式计算。目标进程已经挂起,所以这只会取消 task_suspend 返回码。
现在分离:
(lldb) 分离
当您这样做时,系统会将 mktemp 进程重新设置为其原始父级,
ps -j 并找到您要查找的进程,它将是原始父进程。如果您需要让进程再次运行,请再次使用 lldb 附加到它,并使用与上面调用 task_suspend 相同的参数调用 task_resume。
【讨论】:
expr (void) task_suspend((void *)mach_task_self()) 抱怨 mach_task_self 和 task_suspend 作为未声明的标识符