我试图使用KVM,BSD获取正在运行的进程列表。但是我的NSLog语句中出现了EXC_BAD_ACCESS错误。我该如何处理?
int main(int argc, char *argv[])
{
@autoreleasepool
{
struct kinfo_proc *procs;
size_t count;
int err = GetBSDProcessList(&procs, &count);
if (err) return err;
for (size_t i=0; i!=count; ++i)
{
NSLog(@"%d\n", procs[i].kp_proc.p_pid);
}
free(procs);
}
}
请帮忙。
答案 0 :(得分:0)
我不知道您在哪里获得GetBSDProcessList
函数,但是经过一番搜索,我发现了implementation并且以下代码可以正常工作:
#import <Foundation/Foundation.h>
#import <sys/sysctl.h>
typedef struct kinfo_proc kinfo_proc;
static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount);
int main(int argc, const char *argv[]) {
@autoreleasepool {
kinfo_proc *procList;
size_t count;
int err = GetBSDProcessList(&procList, &count);
if (err) return err;
for (size_t i = 0; i != count; ++i) {
NSLog(@"%d\n", procList[i].kp_proc.p_pid);
}
free(procList);
}
return 0;
}
static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
// Returns a list of all BSD processes on the system. This routine
// allocates the list and puts it in *procList and a count of the
// number of entries in *procCount. You are responsible for freeing
// this list (use "free" from System framework).
// On success, the function returns 0.
// On error, the function returns a BSD errno value.
{
int err;
kinfo_proc *result;
bool done;
static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
// Declaring name as const requires us to cast it when passing it to
// sysctl because the prototype doesn't include the const modifier.
size_t length;
assert(procList != NULL);
assert(*procList == NULL);
assert(procCount != NULL);
*procCount = 0;
// We start by calling sysctl with result == NULL and length == 0.
// That will succeed, and set length to the appropriate length.
// We then allocate a buffer of that size and call sysctl again
// with that buffer. If that succeeds, we're done. If that fails
// with ENOMEM, we have to throw away our buffer and loop. Note
// that the loop causes use to call sysctl with NULL again; this
// is necessary because the ENOMEM failure case sets length to
// the amount of data returned, not the amount of data that
// could have been returned.
result = NULL;
done = false;
do {
assert(result == NULL);
// Call sysctl with a NULL buffer.
length = 0;
err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1,
NULL, &length,
NULL, 0);
if (err == -1) {
err = errno;
}
// Allocate an appropriately sized buffer based on the results
// from the previous call.
if (err == 0) {
result = malloc(length);
if (result == NULL) {
err = ENOMEM;
}
}
// Call sysctl again with the new buffer. If we get an ENOMEM
// error, toss away our buffer and start again.
if (err == 0) {
err = sysctl((int *) name, (sizeof(name) / sizeof(*name)) - 1,
result, &length,
NULL, 0);
if (err == -1) {
err = errno;
}
if (err == 0) {
done = true;
} else if (err == ENOMEM) {
assert(result != NULL);
free(result);
result = NULL;
err = 0;
}
}
} while (err == 0 && !done);
// Clean up and establish post conditions.
if (err != 0 && result != NULL) {
free(result);
result = NULL;
}
*procList = result;
if (err == 0) {
*procCount = length / sizeof(kinfo_proc);
}
assert((err == 0) == (*procList != NULL));
return err;
}
我正在Mac OS X Mojave Beta 2和Xcode 10 Beta 2上运行此代码,这是控制台输出:
.
.
.
2018-06-22 11:22:59.540990+0300 ProcessList[2407:96970] 58
2018-06-22 11:22:59.541040+0300 ProcessList[2407:96970] 55
2018-06-22 11:22:59.541057+0300 ProcessList[2407:96970] 54
2018-06-22 11:22:59.541067+0300 ProcessList[2407:96970] 52
2018-06-22 11:22:59.541075+0300 ProcessList[2407:96970] 51
2018-06-22 11:22:59.541084+0300 ProcessList[2407:96970] 49
2018-06-22 11:22:59.541092+0300 ProcessList[2407:96970] 47
2018-06-22 11:22:59.541101+0300 ProcessList[2407:96970] 46
2018-06-22 11:22:59.541109+0300 ProcessList[2407:96970] 45
2018-06-22 11:22:59.541134+0300 ProcessList[2407:96970] 42
2018-06-22 11:22:59.541257+0300 ProcessList[2407:96970] 41
2018-06-22 11:22:59.541280+0300 ProcessList[2407:96970] 1
2018-06-22 11:22:59.541290+0300 ProcessList[2407:96970] 0
Program ended with exit code: 0