Saturday July 10, 2004 | Surfing With a Linker Alien Rod Evans's Weblog |
|
A recent email discussion reminded me of how fragile, and prevalent, LD_LIBRARY_PATH use it. Within a development environment, this variable is very useful. I use it all the time to experiment with new libraries. But within a production environment, use of this environment variable can be problematic. See Directories Searched by the Runtime Linker for an overview of LD_LIBRARY_PATH use at runtime.
People use this environment variable to establish search paths for applications whose dependencies do not reside in constant locations.
Sometimes wrapper scripts are employed to set this variable,
other times users maintain an LD_LIBRARY_PATH within their
% ldd -s /usr/bin/date
...
find object=libc.so.1; required by /usr/bin/date
search path=/opt/ISV/lib (LD_LIBRARY_PATH)
If you have a large number of LD_LIBRARY_PATH components specified,
you'll see Wrapper scripts attempt to compensate for inherited LD_LIBRARY_PATH use. For example, a version of acroread reveals:
LD_LIBRARY_PATH="`prepend "$ACRO_INSTALL_DIR/$ACRO_CONFIG/lib:\
$ACRO_INSTALL_DIR/$ACRO_CONFIG/lib" "$LD_LIBRARY_PATH"`
The script is prepending its LD_LIBRARY_PATH requirement to any inherited definition. Although this provides the necessary environment for acroread to execute, we're still wasting time looking for any system libraries in the acroread sub-directories. When 64-bit binaries came along, we had a bit of a dilemma with how to interpret LD_LIBRARY_PATH. But, because of its popularity, it was decided to leave it applicable to both class of binaries (64 and 32-bit), even though its unusual for a directory to contain both 64 and 32-bit dependencies. We also added LD_LIBRARY_PATH_64 and LD_LIBRARY_PATH_32 as a means of specifying search paths that are specific to a class of objects. These class specific environment variables are used instead of any generic LD_LIBRARY_PATH setting. Which leads me back to the recent email discussion. Seems a customer was setting both the _64 and _32 variables as part of their startup script, because both 64 and 32 bit processes could be spawned. However, one spawned process was acroread. Its LD_LIBRARY_PATH setting was being overridden by the _32 variable, and hence it failed to execute. Sigh.
Is there a solution to this mess? I guess we could keep bashing
LD_LIBRARY_PATH into submission some way, but why not get
rid of the LD_LIBRARY_PATH requirement altogether? This
can be done. Applications and dependencies can be built to include
a runpath using
Is there a limitation to $ORIGIN use? Yes, as directed by the security folks, expansion of this token is not allowed for secure applications. But then again, for secure applications, LD_LIBRARY_PATH components are ignored for non-secure directories anyway. See Security. For a flexible mechanism of finding dependencies, use a runpath that includes the $ORIGIN token, and try not to create secure applications :-) (2004-07-10 22:20:54.0) Permalink Comments [8] Post a Comment: Comments are closed for this entry. |
|
||||
Posted by Chris Quenelle on July 11, 2004 at 03:23 PM PDT #
Posted by Albert White on July 11, 2004 at 04:14 PM PDT #
Posted by benr on July 11, 2004 at 05:39 PM PDT #
Posted by Rod Eans on July 12, 2004 at 12:35 PM PDT #
Posted by Chris Quenelle on July 20, 2004 at 10:09 PM PDT #
The read only data section is part of the text segment. When the memory image of the file is created, there is typically space between the text and data segments. But within the file image, the text and data segments are typically adjacent. Thus there is no space to put this new string.
If we squeezed a new string between the text and data, the data location has changed, which would invalidate offsets and relocations that had already been established during the link-edit of the file.
Plus, the runpath index from the <tt>.dynamic</tt> table is an index into the dynamic string table <tt>.dynstr</tt>. If we were create a runpath in some other section, and fabricate an index to it, its quite possible that some <tt>ELF</tt> tools will flag this index as invalid.
And, you can't squeeze a new string at the end of the writable data segment either, as this is where the <tt>.bss</tt> has been established, and gets zeroed at runtime.
Posted by Rod Evans on July 22, 2004 at 10:12 AM PDT #
Posted by Seongbae Park on July 23, 2004 at 05:58 PM PDT #
Yes, we've considered all these, but as you point out, they don't fix old objects. And if folks can rebuild their objects they should consider <tt>$ORIGIN</tt> route.
I don't think developers are lazy, they just don't always grasp some of the fine points of delivering a product into an environment where it can be used in multiple ways. Those that know of <tt>$ORIGIN</tt> are using it. Linux implemented it too. The intent of this article was simply to continue spreading the word.
Posted by Rod Evans on July 26, 2004 at 04:32 PM PDT #