以下是使用sysctl来获取PID为50的特定进程的argv的C / Obj-C代码的简短摘要(省略了错误/空值检查)。

...
int getProcessArgs[3] = { CTL_KERN, KERN_PROCARGS, 50 };
sysctl(getProcessArgs, 3, NULL, &length, NULL, 0);
char* processArgs = malloc(length * sizeof(char));
sysctl(getProcessArgs, 3, processArgs, &length, NULL, 0);
...


对sysctl的第一次调用(确定argv字符串数组的大小)成功。返回的长度是〜1600,比我期望的要大,但是我想这并不合理。 Malloc成功。对sysctl的第二次调用返回-1,将errno设置为22,E_INVAL。

我查看了其他代码,包括来自this question的代码,但看不到我的问题。我想念什么?

最佳答案

我尝试将您的代码包装到一个程序中,当查询我自己的进程之一(即与调用sysctl()的进程具有相同uid的进程)时,它可以正常工作并打印出另一个进程的argv等。

“比我预期的要大”的方面是因为返回了进程的环境变量以及命令行参数。 (尚不清楚所有这些信息的格式是什么。)

当询问其他用户的进程时,我从您看到的第二个sysctl中得到了相同的EINVAL。我认为这被认为对其他人的流程不合理,但您会认为第一个sysctl也会失败。

(查询不存在的pid时,第一个sysctl失败,并显示EINVAL。)

这一切似乎都未得到充分记录:在Leopard上,KERN_PROCARGS甚至没有出现在sysctl手册页中。

10-08 16:15