父级中的task_set_bootstrap_port导致子进程挂起

时间:2011-08-17 04:30:25

标签: objective-c macos osx-lion

{1}的行为在OS X 10.6和10.7之间发生了变化。在10.6中,这有效:

task_set_bootstrap_port

// parent process
mach_port_t parent_recv_port = MACH_PORT_NULL;
setup_recv_port (&parent_recv_port);
task_set_bootstrap_port(mach_task_self(), parent_recv_port); 
NSTask *qtTask = [[NSTask alloc] init];
[qtTask setLaunchPath:...]; 
[qtTask launch];
...

但是,在10.7中,子进程在父调用// child process int main (int argc, const char * argv[]) { mach_port_t parent_recv_port = MACH_PORT_NULL; task_get_bootstrap_port(mach_task_self(), &parent_recv_port); ... } 之后不立即执行main的第一行 - 它等待父进程终止。 (虽然子进程会立即显示在-launch。)

我已将问题缩小到调用ps。当呼叫不存在时,子进程不会挂起。并且,如果我在task_set_bootstrap_port -

之后立即将引导端口恢复为原始端口
task_set_bootstrap_port

- 然后子进程也不会挂起。

错误处理代码已从上面省略,但实际上它是在每次调用后检查错误。没有错误。

那么,任何想法为什么task_set_bootstrap_port(mach_task_self(), bootstrap_port); 的行为从10.6变为10.7?有解决方法吗?

约束:

  • 需要访问task_set_bootstrap_port才能转到mach_port_t
  • Runloop可能不存在,因此无法使用IOSurfaceLookupFromMachPortNSMachPort

1 个答案:

答案 0 :(得分:2)

Apple开发人员技术支持部门告诉我,暂时更改引导端口,正如此代码所做的那样,从未保证能够正常工作。在这种情况下,XPC在更改后尝试向boostrap端口发送消息,但这种情况发生了故障,因此事情已经破裂。

快速解决方法是在父进程中使用bootstrap_register(虽然已弃用),在子进程中使用bootstrap_look_up。这允许孩子通过名称(字符串)查找父级并从中获取端口。