From: Daniel A. S. <da...@us...> - 2007-12-18 10:22:28
|
On 18/12/2007, at 4:26, Kevin Walzer wrote: > Running Tk 8.5 (RC 5) with a rebuilt version of Python 2.5.1 on > Leopard > 10.5.1, I this message repeated endlessly in Console when I run IDLE > (the Python editor written in Tk): > > THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTION > ALITY___YOU_MUST_EXEC__() > to debug. the best way to find out what Python is doing that leads to this is to follow the instructions in the message ;-) i.e. start IDLE under gdb, put a future-break at the indicated symbol and run... I would be interested to see the gdb backtrace once it stops at that breakpoint > I've seen this message in other newsgroups and understand that it > reflects some changes in Core Foundation. Is this a harmless > message, or > does it reflect some bug in Tk that will cause unexpected problems? the only time I have seen this message with tcl was with pre-release versions of Leopard, where the use of CoreFoundation in the atfork child handler of tclMacOSXNotify.c was causing an abort due to this issue, that was fixed 2007-06-23 (the forced abort on use of CF after fork was since removed in Leopard, c.f. below). On Leopard, that fix makes naked fork (i.e. not immediately followed by exec) once again unusable in a corefoundation-enabled tcl, even when tcl is unthreaded (the CF tcl notifier always uses a separate notifier thread to run select). the only way to use naked fork on Leopard from within tcl is to configure tcl with --disable-corefoundation, but that OTOH precludes use of TkAqua (which requires the CF notifier). I do not know why IDLE or python generally would be calling fork not immediately followed by exec, whatever happens between fork and exec ends up calling CF somehow, this could occur e.g. by calling a tcl API that runs the tcl event loop (which would cause the CF notifier thread to be recreated in the child). The only use of fork & exec inside tcl itself is the [exec] implementation, I've been planning to investigate using posix_spawn() instead when available (e.g. on Leopard), that would eliminate the need to run the CF notifier atfork handlers completely (in fact on non-64bit they already don't run now because we use vfork() instead of fork() in [exec]) for more background on this see the CF release notes http://developer.apple.com/releasenotes/CoreFoundation/ CoreFoundation.html (with correction applied s/async-cancel-safe/async-signal-safe/): > 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-signal-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-signal-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. for the relevant SUSv3 bits see http://www.opengroup.org/onlinepubs/009695399/functions/fork.html > If a multi-threaded process calls fork(), the new process shall > contain a replica of the calling thread and its entire address > space, possibly including the states of mutexes and other > resources. Consequently, to avoid errors, the child process may > only execute async-signal-safe operations until such time as one of > the exec functions is called. http://www.opengroup.org/onlinepubs/009695399/functions/ xsh_chap02_04.html > The following table defines a set of functions that shall be either > reentrant or non-interruptible by signals and shall be async-signal- > safe. Therefore applications may invoke them, without restriction, > from signal-catching functions: <snip> > All functions not in the above table are considered to be unsafe > with respect to signals. Cheers, Daniel -- ** Daniel A. Steffen ** ** <mailto:da...@us...> ** |