如何在 C 中的进程完成后跟踪子进程使用的内存

how to trace memory used by a child process after the process finished in C

我有一个进程使用 execve(2) 系统调用派生一个子进程来执行可执行程序

父进程等待子进程完成使用 wait4(2) 系统调用

我需要知道子进程 运行 的应用程序 运行 使用的时间和内存
我使用 wait4(2) 系统调用返回的 (rusage) 对象来获取我想要的时间值,但经过一些研究后,我发现应用程序使用的内存无法通过同一个 (usage) 对象实现,因为它已经不现在以这种方式支持

一种方法是使用 /proc 伪文件系统并解析 /proc/[pid]
目录中的状态或 statm 文件 假设我想解析 /proc/[pid]/status
我在这个文件中需要的是指定 KB

中数据使用的内存的字段 vmdata 当我在子进程完成之前读取文件时,未显示字段 vmdata "it's missing from the file!!" 显然进程未完成!所以我无法准确确定用于孔工作的内存

当我在子进程完成后读取文件时,目录 /proc/[pid] 将被删除!我建议当进程结束时,进程数据会被释放

请 !!解决这个问题的任何想法或其他方式的任何想法?
谢谢...

VmData 字段似乎只存在于 运行ning 进程中。我不知道你为什么决定不这样做。只需 运行 grep VmData /proc/$$/status,您就会在当前的 shell 流程中看到它。

你的问题中有三个有趣的时间点。第一个是当您的 child 进程处于 运行ning 时。第二个是当它不再是运行ning,而是以丧尸的形式存在,第三个是你收割它之后,它不存在了。您似乎错过了第 2 点。

如果你想在进程处于僵尸状态时捕获它(即 - 它已经退出,但尚未收割)你将需要找到一种方法来通知它已完成而不调用 wait, 这将使它消失。我推荐的方法是注册一个 SIGCHLD 处理程序。它会在您的进程存在时被调用,但不会将其从系统中删除。到那个时候,/proc/pid/status 仍然存在。

不幸的是,VmData 不存在僵尸进程。您的选择是定期采样 VmData,或者在进程即将终止时停止进程,但实际上尚未这样做。

有一种无竞争的方法可以做到这一点,但不幸的是,它需要使用有点黑魔法的 ptrace 系统调用。如何使用 ptrace 的完整解释超出了本答案的范围。然而,简而言之,您的 child 进程在调用 execve 之前,使用 PTRACE_TRACEME 参数调用 ptrace。然后,您的 parent 进程将成为您的 child 进程的调试器。每当您的 child 进程即将执行某些特殊操作时,它都会收到 wait 通知。

这需要花一些时间来尝试调用,但这会让您知道您的 child 何时即将退出,但实际上尚未退出。