Debugging your shared library with LD_PRELOAD
This morning, I've replied to one posting on comp.unix.solaris about dbx and LD_PRELOAD (google groups doesn't seem to have my replies yet). It reminded me of my experience with dbx and LD_PRELOAD which I'd like to share.I needed to debug and test my shared library. LD_PRELOAD seemed to be the easiest way to do so (if you don't know what LD_PRELOAD is, you may want to take a look at manpage ld.so.1(1) or the wonderful Linker and Libraries Guide).
Without much thinking, I did the following:
$ LD_PRELOAD=...my library... $ dbx ...my program...And I immediately got the linker error:
ld.so.1: ....: fatal: ... wrong ELF class: ELFCLASS32Dang. The real dbx is 64bit on SPARC but my library is 32bit. Obviously a 32bit library and a 64bit executable don't mix together very well.
So I tried the following:
$ dbx ...my program... (dbx) LD_PRELOAD=...my library... (dbx) export LD_PRELOAD (dbx) runand it worked fine, or so it seemed. Dbx loads all libraries that the executable depends on in advance (if you have used dbx, you'll remember seeing those "Reading ....so.1" lines when dbx reads your program). But LD_PRELOAD'ed library is loaded when the program is executed, not in advance. That means dbx loaded both the original shared library and my shared library in LD_PRELOAD.
This didn't affect the execution of my program, but it affected which symbol dbx sees. Since both original and my own shared libraries are loaded, whenever I wanted to inspect a symbol in the library, dbx saw two different copies. Sometimes it asked me for which version to really use (like when setting breakpoints or calling functions), but sometimes it just used the original (like when printing global variables). This was confusing, and so I cried help to the dbx guy and he taught me the following solution:
(dbx) loadobject -list ... (dbx) loadobject -unload ...the original library...which unloaded the unnecessary original library and the problem was solved.
Well, technically the above was the ideal way. But I'm lazy and didn't want to do "loadobject" thing everytime I start my dbx. And so I ended up doing the following:
$ LD_PRELOAD_32=...my library... dbxwhich is sort of a work-around. This wouldn't have worked if my library were 64bit and interfered with dbx in some ways. I guess this is one of those cases where you prefer a little work around than a proper solution.
( Jul 30 2004, 11:24:52 AM PDT ) Permalink Comments [1]
Post a Comment:
Comments are closed for this entry.


Posted by Chris Quenelle on July 30, 2004 at 02:17 PM PDT #