From: Jonathan Paisley Date: 2005-05-18T06:40:31+09:00 Subject: Re: IRB, Mac OS X, command-line require via "-r" and Bus Errors On Wed, 18 May 2005 04:42:47 +0900, nobu.nokada wrote: > Hi, > > At Wed, 18 May 2005 03:30:31 +0900, > Jonathan Paisley wrote in [ruby-talk:142938]: >> > Is this function called at each time when .so is loaded, and >> > the area pointed by _NSGetArgv() shouldn't be changed? >> > >> > I suspect that system dependent initialization of arguments >> > should be integrated. >> >> The _NSGetArgv function would appear to be an private function (inferring >> this from the leading underscore), so perhaps it'd be inappropriate to >> use it in the ruby core. Having said that, it is declared in ... >> >> Perhaps an alternative would be to modify set_arg0() to change the >> non-first argument to be empty C strings ("") rather than NULL? > > "-AppleLanguages" can be disappeared? 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. 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. > What about this? > > void > ruby_sysinit(argc, argv) > int *argc; > char ***argv; > { > #if defined(__APPLE__) && (defined(__MACH__) || defined(__DARWIN__)) > int i, n = *argc, len = 0; > char **v1 = *argv, **v2 = ALLOC_N(char*, n + 1); > MEMCPY(v2, v1, char*, n); > v2[n] = 0; > for (i = 0; i < n; ++i) { > v1[i] = strdup(v1[i]); > } > *argv = v2; > #elif defined(__MACOS__) && defined(__MWERKS__) > *argc = ccommand(argv); > #endif > } 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. I still feel the solution is either to use empty strings rather than NULL for filling the remaining argv pointers in set_arg0, or link ruby on OSX to CoreFoundation by default. (I haven't tested whether the latter solves the problem at hand - it should though). Please let me know if I'm not making sense! :) Thanks Jonathan