Re: ...Unhappy Childhood Persists
Re: ...Unhappy Childhood Persists
- Subject: Re: ...Unhappy Childhood Persists
- From: Jim Magee <email@hidden>
- Date: Tue, 11 Mar 2003 16:15:51 -0500
On Tuesday, March 11, 2003, at 02:56 PM, Lance Drake wrote:
Does your application link against any Apple-specific frameworks
other than libSystem? There should be quite a few references in the
archives about "No other Apple frameworks, other than libSystem, can
be combined with fork() and expect consistent results." You must
immediately call exec() or _exit() (with only signal-safe calls
between these and the fork() call).
The process of elimination was finally brought to bear on this effort.
Yes, there ARE other frameworks linked with the tool - so I went to
the trouble of pulling out all frameworks and code - down to the
minimum required to execute to the point it was crashing (Linked
foundations are now: CoreFoundation and IOKit - removing Carbon,
SystemConfiguration and DiskArbitration). Things appear now to be
stable enough to execute that "runLoopSource =
IONotificationPortGetRunLoopSource( sNotifyPort );" call which is
where the 'complete' version konks out.
Note that even IOKit potentially can get you in trouble.
CoreFoundation isn't officially supported in fork()ing applications
either, but it does go out of its way to try and make things work
"post-fork()" anyway. One thing it doesn't do is reset the main
runloop post-fork(). There should be something in the archives about
doing that manually in your own code post-fork() (if you insist on
doing the unsupported thing and continue to use these frameworks
post-fork).
Where I am at the moment is that it looks like I will have to take the
fork/execve route - which seems unnecessary, considering the fact that
it all works fine (as is) in 10.2.4 and nobody has anything to point
to that represents a big change in the mach world from the 10.1 days.
I suppose I should say (in my best Jerry Seinfeld) "HEY!... whatever
works!", but I'd really like to find out why this is failing.
You are just getting "luckier" in the 10.2.4 runs. What you are trying
to do is equally unsupported in either build.
All those other frameworks have globals initialized with names of Mach
ports embedded in them. After the fork(), the memory is copied into
the child, but not the ports. Eventually the port names (copies of
which are lying in memory waiting to jump out and bite you) get reused
in the child for some other purpose. When you do execute any of the
code from those other frameworks that depend on those ports names, all
kinds of craziness ensues.
Some of those data structures may actually affect dyld's ability to
resolve symbol names in the child (like the setsid() call which only
the child calls). That's why being pre-bound sometimes alters this
behavior.
We have tried to "fix" this issue by putting in "at-fork()" handlers in
these other frameworks. The problem is that the dependency ordering of
the frameworks can be different in the child during the run of these
handlers than they were during the first initialization in the parent.
There is no good way (that we have found) to encapsulate these new
dependencies so that the child could run them in the proper order. So,
that's still a craps-shoot as to whether it would work or not. Until
we have a solution that works reliably, we have to declare this
behavior "offlimits."
We understand that it is frustrating (especially to Unix programmers
who are forced into using some of these other frameworks for "just one
thing"), and have been working hard on a proper solution. Sorry for
the inconvenience.
--Jim
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.