为什么sysctl在Mac OS X上生成E_INVAL?

下面是一个C / Obj-C代码的简化(错误/空检查省略)片段,它使用sysctl来获取PID 50的特定进程的argv。

... 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。

我已经查看了其他代码,包括来自这个问题的代码,但是看不到我的问题。 我错过了什么?

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

“大于我预期的”方面是因为返回了进程的环境变量以及命令行参数。 (所有这些信息的格式都不明显。)

在询问不同用户的进程时,我从您看到的第二个sysctl获得相同的EINVAL。 我想这对其他人的过程被认为是不合理的好奇心,但你认为第一个sysctl也会失败。

(当查询不存在的pid时,第一个sysctl因EINVAL而失败。)

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