I’ve been working on enum again recently and got completely stuck in getopt_long() return values. I don’t want to bore you with details, so let me cut to the chase: I needed a way to look into what getopt_long() is actually doing.
Now, there are a few ways to figure out the doings of a function. If it’s your own code, you could just go ahead and add a few printf()s to see if your variables fill up as intended. Then you could use gdb to walk through your running code. But what if you want to do so in functions outside the scope of your own code? In my case: getopt, i.e. libc?
Obviously, you can download the library, add your printf() stuff, compile and install it, and see it all happening. But libc isn’t exactly small, fast-compiling, and you really don’t want to mess it up and have it installed on your system. So how about just taking what you actually care for and push it in? This is nothing experimental or particularly “hacky”. I just don’t want to forget about it and maybe someone can make use of it. So here we go…
Download your libc sources to a new directory and copy the files you need. Try something like
mkdir -p /tmp/getopt/mygetopt cd /tmp/getopt apt-get source eglibc cp eglibc-*/posix/getopt* mygetopt/ cd mygetopt
Now write up a primitive Makefile:
all: libmygetopt.so libmygetopt.so: getopt.c getopt1.c getopt_int.h getopt.h gcc -shared -Wl,-soname,libmygetopt.so.1 -fPIC -o libmygetopt.so.1.0.0 getopt1.c getopt.c ln -s libmygetopt.so.1.0.0 libmygetopt.so.1 ln -s libmygetopt.so.1 libmygetopt.so clean: $(RM) libmygetopt*
In order for this to actually work, I fiddled around with a few #ifdef’s in getopt.c. But that’s something you’ll probably find out yourselves. You should at least be able to compile it (‘make’ it). Now put a printf statement somewhere in the function you want to inspect. Recompile the lib and then go back to your actual program.
Running the program ist easy.
src/enum -p1 1 3 1.0 2.0 3.0
Surprisingly, running it using your own getopt version is just as easy. Just push your library in:
LD_PRELOAD=libmygetopt.so LD_LIBRARY_PATH=/tmp/getopt/mygetopt:$LD_LIBRARY_PATH src/enum -p1 1 3 Yo, Ulrich, my getopt version is waaaay cooler than yours! Yo, Ulrich, my getopt version is waaaay cooler than yours! 1.0 2.0 3.0
If you’re disappointed now, that’s your own fault. I said it in the beginning, this is nothing special. It’s not my idea. It’s something that developers all use all the time … or something like that. In case you didn’t know about it, good for you. Otherwise, sorry for reading my memory dump.