On Wed, 18 May 2005 11:50:28 +0900, nobu.nokada wrote:


> At Wed, 18 May 2005 06:40:31 +0900,
> Jonathan Paisley wrote in [ruby-talk:142962]:
>> I'm not entirely sure what you mean here. The CFRuntime code removes -AppleLanguages 
>> arguments from the command line, but the code that does it crashes if there are
>> NULLs present. We see the error if a ruby script calls set_arg0 before this happens.
>> set_arg0 sets argv[0], and sets argv[1 to argc-1] to NULL.
> 
> The code "around line 720" you posted doesn't remove
> -AppleLanguages, but copies it to __CFAppleLanguages.  So I
> guess it might be used later if it was given.

Sorry, you are right. I misread the CFRuntime code. It just copies the
argument to __CFAppleLanguags.

> 
>> One of my suggestions was: in set_arg0 use empty strings ("") instead
>> of NULL values in set_arg0. This would prevent the crash.
>> 
>> An alternative would be just to link ruby with the CoreFoundation framework. That way,
>> the CFRuntime initialisation code should get executed before ruby initialises, and
>> the problem goes away.
> 
> Does the initialization run just once in the whole process?

Yes, just once. You can see if you look at the complete source:

  http://darwinsource.opendarwin.org/10.4.1/CF-368.1/Base.subproj/CFRuntime.c

The whole __CFInitialize function is protected by a static 'done' variable.



>> The problem with this is that it causes set_arg0 to not have the desired effect.
>> 
>> set_arg0 is designed to change the process name, as it appears in 'ps' output. 
>> To do this, it's necessary to overwrite the existing argument strings.
>> Note: what I mean here is overwriting the character data in the existing
>> strings, and not changing string pointers in the argv array. 'ps' (or in
>> kernel process info, depending on OS) reads directly from the argument
>> strings, not going through any pointers in an argv array.
>> 
>> The upshot is that changing argv for ruby in the proposed ruby_sysinit
>> means that a later set_arg0 will not change the necessary kernel-known
>> arguments. 
> 
> No, it duplicates the argument strings and remains them in the
> original argv (i.e., pointed from *_NSGetArgv()), but let the
> entire string area to be pointed by newly allocated argv, which
> is returned to the caller.

The effect your describe is right, but my point is that set_arg0 (defined
in ruby.c) needs to operate on the original argv in order to be able to
change the process name as reported by 'ps'. If set_arg0 sees strdup()-ed
strings, its changes will have no effect.