3

Is it possible to pass arguments to my library, which is loaded with LD_PRELOAD:

LD_PRELOAD=lib.so ./program

How can I pass arguments to this library?

Flexo
  • 87,323
  • 22
  • 191
  • 272

1 Answers1

8

Normally I'd do this by using environment variables. For example with something like:

#include <iostream>
#include <stdlib.h>

void init() __attribute__ ((constructor));
void init() {
  std::cout << "Init: " << getenv("MYLIB") << std::endl;
}

lets you do:

MYLIB=hi LD_PRELOAD=./test.so /bin/echo
Init: hi

this doesn't have to be used in a constructor (which is a GCC extension), but that's often a handy place to use them.

What I've done in the past has been to use this, combined with a shell script wrapper that looks like it's a "normal" application. The shell script takes its arguments and pushes them into the environment variables your library expects before calling exec to load the program you want to interpose. It "feels" right to users that way without being too fragile or intrusive.

You could also do this by reading /proc/self/cmdline to read the command line of the current process directly if you'd rather. Personally I'd keep clear of interfering with the process you're working with as much as possible though.

Flexo
  • 87,323
  • 22
  • 191
  • 272
  • @ChercheurChercheur that's fine - I only used iostreams for printing, you can trivially make it into stdio and there's nothing else C++ specific besides that. (The constructor attribute works in C, it calls the function automatically when the library gets loaded, not a C++ constructor) – Flexo Jul 15 '12 at 17:20
  • Please, i want to pass more that one argument to my lib, is that possible? – Chercheur Chercheur Aug 04 '12 at 16:54
  • @ChercheurChercheur - use multiple environment variables or pass a list in through the environment variable. – Flexo Aug 04 '12 at 16:56
  • i do like that for example: MYLIB=hi,hello LD_PRELOAD=./test.so /bin/echo ? – Chercheur Chercheur Aug 04 '12 at 16:58
  • @ChercheurChercheur - yes that would be one way, or you could do `MYLIBARG1=val1 MYLIBARG2=val2 LD_PRELOAD=./test.so /bin/bech` or make the single list name/value pairs: `MYLIB='k1=v1:k2=v2' LD_PRELOAD ...` – Flexo Aug 04 '12 at 17:00