当 运行 作为 child 进程时,OpenGL window 无法在 xcode (7.2) 中打开
OpenGL window doesn't open in xcode (7.2) when run as a child process
我在 OS X 10.10.5 和 Xcode 7.2。我有一个程序生成一个 child 进程到 运行 使用 OpenGL/GLUT 的可视化,即
pid_t childpid;
childpid = fork();
if(childpid == 0) { // this is the child process
glutInit(&argc, argv);
...
}
else{ // this is the parent process that does something else
...
}
当我在 Xcode 中 运行 时,程序从未从 glutInit returns。相反,如果我使用 parent 过程进行可视化,而 child 到 运行 其他所有内容,即
if(childpid != 0) { // this is the parent process
glutInit(&argc, argv);
...
}
...
然后 OpenGL window 弹出,整个程序 运行 没问题。此外,如果我在 Xcode 之外的终端中使用 Makefiles 构建时 运行 原始版本(使用 child 进行可视化),一切 运行 都很好。
有什么可能导致这种情况的想法吗?
我无法在 Xcode 内调试很远的东西,因为调试器总是遵循 parent 过程。如果我尝试通过 Debug->Attach to process 附加到 child 进程,我得到一个错误: "Xcode couldn't attach to “J2”. “J2” does not support a debuggable architecture." 我在 xcode 中发现了关于附加到其他进程的最后一个问题的一些问题,但解决方案对我不起作用。
除了一些 exec()
或 _exit()
.
我将引用 Leopard CoreFoundation 框架发行说明。我不知道它们是否仍然在线,因为 Apple 倾向于替换而不是扩展 Core Foundation 发行说明。
CoreFoundation and fork()
Due to the behavior of fork(), CoreFoundation cannot be used on the
child-side of fork(). If you fork(), you must follow that with an
exec*() call of some sort, and you should not use CoreFoundation APIs
within the child, before the exec*(). The applies to all higher-level
APIs which use CoreFoundation, and since you cannot know what those
higher-level APIs are doing, and whether they are using CoreFoundation
APIs, you should not use any higher-level APIs either. This includes
use of the daemon() function.
Additionally, per POSIX, only async-cancel-safe functions are safe to
use on the child side of fork(), so even use of lower-level
libSystem/BSD/UNIX APIs should be kept to a minimum, and ideally to
only async-cancel-safe functions.
This has always been true, and there have been notes made of this on
various Cocoa developer mailling lists in the past. But CoreFoundation
is taking some stronger measures now to "enforce" this limitation, so
we thought it would be worthwhile to add a release note to call this
out as well. A message is written to stderr when something uses API
which is definitely known not to be safe in CoreFoundation after
fork(). If file descriptor 2 has been closed, however, you will get no
message or notice, which is too bad. We tried to make processes
terminate in a very recognizable way, and did for a while and that was
very handy, but backwards binary compatibility prevented us from doing
so.
换句话说,除了执行一个新程序之外,在 fork()
的子端做任何事情都是不安全的。
除了一般的 POSIX 禁令外,oft-mentioned 的解释是:a) 现在几乎所有 Cocoa 程序都是多线程的,GCD 等等。 b)当你fork()
时,只有调用线程存活到子进程中;其他线程就消失了。由于这些线程可能一直在操纵共享资源,因此子进程不能依赖于具有理智的状态。例如,malloc()
实现可能有一个锁来保护共享结构,并且该锁可能在 fork()
时由 now-gone 线程之一持有。因此,如果剩余的线程试图分配内存,它可能会无限期地挂起。其他共享数据结构可能只是处于损坏状态。等等
我在 OS X 10.10.5 和 Xcode 7.2。我有一个程序生成一个 child 进程到 运行 使用 OpenGL/GLUT 的可视化,即
pid_t childpid;
childpid = fork();
if(childpid == 0) { // this is the child process
glutInit(&argc, argv);
...
}
else{ // this is the parent process that does something else
...
}
当我在 Xcode 中 运行 时,程序从未从 glutInit returns。相反,如果我使用 parent 过程进行可视化,而 child 到 运行 其他所有内容,即
if(childpid != 0) { // this is the parent process
glutInit(&argc, argv);
...
}
...
然后 OpenGL window 弹出,整个程序 运行 没问题。此外,如果我在 Xcode 之外的终端中使用 Makefiles 构建时 运行 原始版本(使用 child 进行可视化),一切 运行 都很好。
有什么可能导致这种情况的想法吗?
我无法在 Xcode 内调试很远的东西,因为调试器总是遵循 parent 过程。如果我尝试通过 Debug->Attach to process 附加到 child 进程,我得到一个错误: "Xcode couldn't attach to “J2”. “J2” does not support a debuggable architecture." 我在 xcode 中发现了关于附加到其他进程的最后一个问题的一些问题,但解决方案对我不起作用。
除了一些 exec()
或 _exit()
.
我将引用 Leopard CoreFoundation 框架发行说明。我不知道它们是否仍然在线,因为 Apple 倾向于替换而不是扩展 Core Foundation 发行说明。
CoreFoundation and fork()
Due to the behavior of fork(), CoreFoundation cannot be used on the child-side of fork(). If you fork(), you must follow that with an exec*() call of some sort, and you should not use CoreFoundation APIs within the child, before the exec*(). The applies to all higher-level APIs which use CoreFoundation, and since you cannot know what those higher-level APIs are doing, and whether they are using CoreFoundation APIs, you should not use any higher-level APIs either. This includes use of the daemon() function.
Additionally, per POSIX, only async-cancel-safe functions are safe to use on the child side of fork(), so even use of lower-level libSystem/BSD/UNIX APIs should be kept to a minimum, and ideally to only async-cancel-safe functions.
This has always been true, and there have been notes made of this on various Cocoa developer mailling lists in the past. But CoreFoundation is taking some stronger measures now to "enforce" this limitation, so we thought it would be worthwhile to add a release note to call this out as well. A message is written to stderr when something uses API which is definitely known not to be safe in CoreFoundation after fork(). If file descriptor 2 has been closed, however, you will get no message or notice, which is too bad. We tried to make processes terminate in a very recognizable way, and did for a while and that was very handy, but backwards binary compatibility prevented us from doing so.
换句话说,除了执行一个新程序之外,在 fork()
的子端做任何事情都是不安全的。
除了一般的 POSIX 禁令外,oft-mentioned 的解释是:a) 现在几乎所有 Cocoa 程序都是多线程的,GCD 等等。 b)当你fork()
时,只有调用线程存活到子进程中;其他线程就消失了。由于这些线程可能一直在操纵共享资源,因此子进程不能依赖于具有理智的状态。例如,malloc()
实现可能有一个锁来保护共享结构,并且该锁可能在 fork()
时由 now-gone 线程之一持有。因此,如果剩余的线程试图分配内存,它可能会无限期地挂起。其他共享数据结构可能只是处于损坏状态。等等