James Adam <james.adam / gmail.com> wrote:

> I'm at the end of my tether, and can only see
> this as being a bug in Mac OS X. However, I can't even find a reference
> for memcmp in __CFInitialize (see
> http://darwinsource.opendarwin.org/10.4/CF-368/Base.subproj/CFRuntime.c,
> the Darwin source for Tiger).

Allright, here's some more data.

As already shown, this happens when calling irb with a request to load a
compiled extension through the '-r' option. *Any* compiled extension. So
to track this problem down a little bit more I created a simple dummy
extension but linked with the debug version of the CoreFoundation
framework, to hopefully be able to have more info in the stack trace.

Here's the code of the dummy extension.

## [begin test.c] ##

#include <ruby.h>
void Init_test( void )
{
    rb_define_module( "Test" );
}

## [end test.c] ##

And here is how it is being built on my machine:

gcc -fno-common \
-pipe \
-I. \
-I/opt/local/include \
-I/opt/local/lib/ruby/1.8/powerpc-darwin8.0.0 \
-I/opt/local/lib/ruby/1.8/powerpc-darwin8.0.0 \
-O \
-c test.c

cc -dynamic \
-bundle \
-undefined suppress \
-flat_namespace \
-L/opt/local/lib \
-lruby \
-ldl \
-lobjc \
-o test.bundle \
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFound
ation_debug \
test.o

Now let's see what we get:

% irb
irb(main):001:0> require 'test'
2005-05-17 13:31:03.113 irb[2408] CFLog (0): Assertions enabled
=> true

Looks like it works and we have some debug messages coming from the
debug version of the CoreFoundation framework. Now let's see what the
crashing version gives us:

% irb -r test
../test.bundle: [BUG] Bus Error
ruby 1.8.2 (2004-12-25) [powerpc-darwin8.0.0]

As expected, but this time the stack trace is a little bit more explicit
(showing here only the relevant lines):

Thread 0 Crashed:
0 libSystem.B.dylib     0x900033c0 strcmp + 192
1 CoreFoundation_debug  0x004bbfc4 __CFInitialize+600 (CFRuntime.c:720)

Two things:
- The crashing memcmp/bcmp that we got before is actually an strcmp
(probably inlined in the non-debug version).
- This strcmp is called from CFRuntime.c *around* line 720.

"Around" line 720 and not "at" line 720 because it appears that the
CoreFoundation framework that ships with 0S X is a little bit different
than the one for which we can have the sources.

Now, if we look at CFRuntime.c and find the strcmp closest to line 720
we fine this block of code:

{
  CFIndex idx, cnt;
  char **args = *_NSGetArgv();
  cnt = *_NSGetArgc();
  for (idx = 1; idx < cnt - 1; idx++) {
    if (0 == strcmp(args[idx], "-AppleLanguages")) {
      CFIndex length = strlen(args[idx + 1]);
      __CFAppleLanguages = malloc(length + 1);
      memmove(__CFAppleLanguages, args[idx + 1], length + 1);
      break;
    }
  }
}

And not so surprisingly, this block is noodling with command line
arguments. What we need to know now is WHY exactly does this strcmp
crash.

-- 
Luc Heinrich - lucsky / mac.com