20

I am using LD_PRELOAD to hook a library function, and in Linux it works perfectly. But I cannot figure out how to do the equivalent in OSX.

The setup I have on Linux is as follows:

The code is:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include <ruby.h>

void
rb_raise(unsigned long exc, const char *fmt, ...)
{
  static void (*libruby_rb_raise)
    (unsigned long exc, const char *fmt, ...) = NULL;

  void * handle;
  char * error;

  if (!libruby_rb_raise) {
    handle = dlopen("/path/to/libruby.so",
                    RTLD_LAZY);
    if (!handle) {
      fputs(dlerror(), stderr);
      exit(1);
    }
    libruby_rb_raise = dlsym(handle, "rb_raise");
    if ((error = dlerror()) != NULL) {
      fprintf(stderr, "%s\n", error);
      exit(1);
    }
  }

  // ...code... 

  return Qnil;
}

Which I then compile with:

gcc -Wall -O2 -fpic -shared -ldl -g -I/path/to/includes/ -o raise_shim.so raise_shim.c

I then execute with:

LD_PRELOAD=./raise_shim.so ruby

All of the above works well on Linux, what is the equivalent for each step to get this working on OSX? I have googled this and have not been able to get it to work with the information provided as the info for some of the steps are missing.

Thanks in advance!

Kevin
  • 53,822
  • 15
  • 101
  • 132
horseyguy
  • 29,455
  • 20
  • 103
  • 145

1 Answers1

21

Take a look at DYLD_INSERT_LIBRARIES. That's the variable you're looking for.

See also this answer.

Isaiah Norton
  • 4,205
  • 1
  • 24
  • 38
Dan Fego
  • 13,644
  • 6
  • 48
  • 59
  • Thanks, I knew this much :) But it's not just as simple as setting that i found, i have to make major modifications to my source, and the compilation step is different, too. It is the execution of these steps i cannot figure out how to do :( – horseyguy Dec 15 '11 at 04:41
  • Are you sure? I'm pretty sure I've used this before (but not 100% -- I just know I've looked at it. :P) What exactly isn't working? – Dan Fego Dec 15 '11 at 04:44
  • 1
    What line exactly should i use to build the library, the one (shown in the question above) no longer works. do i have to modify my source code in any way? What is this i hear about needing to set another `FLAT_NAMESPACES` macro, and something about `DYLD_INTERPOSE`I know it's not simply a matter of substituting `DYLD_INSERT_LIBRARIES` for `LD_PRELOAD`. – horseyguy Dec 15 '11 at 04:48
  • Hmm, I'm not sure without a Mac in front of me. Are you saying that the line to build it no longer works, i.e. it won't build, or that the library's symbol isn't taking precedence when using `DYLD_INTERPOSE`? Perhaps ruby on OSX is different? These are just possibilities, but I'll have to check later. Though I'm sure someone else will come to the rescue in the meantime. :) – Dan Fego Dec 15 '11 at 04:51
  • Hi, i changed the `gcc` line when building on osx to `gcc -Wall -ldl -I/path/to/includes -o lib_overrides.dylib -dynamiclib ./raise_shim.c` and i get a bunch of symbol lookup errors, any idea? – horseyguy Dec 16 '11 at 02:32