A foo() in seperate .so's resolves to the wrong library
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > A foo() in seperate .so's resolves to the wrong library




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    A foo() in seperate .so's resolves to the wrong library  
Steven Reddie


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-20-04 07:51 AM

Hi All,

I've got a problem where I have two .so's that contain a function with
the same name and the loader picks just one to be used for resolving
all references.  I'm sure it's a common problem, but I'm having
trouble explaining it, so a diagram:

+-------------------+
|      program      |
+-------------------+
|            |
V            V
+-------+    +-------+
| a1.so |    | b1.so |
+-------+    +-------+
|            |
V            V
+-------+    +-------+
| a2.so |    | b2.so |
+-------+    +-------+

a1.so and a2.so are two libraries of a particular component.  b1.so
and b2.so are two libraries of a seperate independent component.
a1.so and b1.so don't contain any clashing symbols.  a2.so and b2.so
each have a function with the same name, let's say foo().  When a1.so
was linked, the linker saw that it could resolve foo() against a2.so
and flagged it as such.  When b1.so was linked, the linker saw that it
could resolve foo() against b2.so and flagged it as such.  However,
when linking a1.so and b1.so into program with a line such as (forget
about the missing lib prefix):
ld -o program program.o -la1 -lb1
the resulting executable when loaded resolves foo() against a2.so for
both a1.so and b1.so.

On Windows I get the behaviour that I need which is that since b1.so
was shown that it could resolve foo() against b2.so it will only
resolve it against that library at runtime.  I need this behaviour
since a2.so and b2.so are actually different versions of the same
library and the program must be able to simultaneouly use components
which may use differerent versions of this library.

Any help is appreciated.

Regards,

Steven





[ Post a follow-up to this message ]



    Re: A foo() in seperate .so's resolves to the wrong library  
Paul Pluzhnikov


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-22-04 11:08 PM

smr@essemer.com.au (Steven Reddie) writes:

> I've got a problem where I have two .so's that contain a function with
> the same name and the loader picks just one to be used for resolving
> all references.  I'm sure it's a common problem [...]

This is *not* a "problem". This is how dynamic linker works (and how
it is supposed to work) on UNIXes (AIX being notable exception).

> On Windows I get the behaviour that I need ...

That is Windows-specific behaviour. You'll need to re-design yor
program if you must replicate this on UNIX.

One approach is for a1.so to have a table of function pointers,
and to initialize them with 'dlsym(a2_handle, "foo")' instead of
linking a1.so against a2.so directly.

However ...

> I need this behaviour
> since a2.so and b2.so are actually different versions of the same
> library and the program must be able to simultaneouly use components
> which may use differerent versions of this library.

... if your target is Solaris or Linux, you might be able to "coerce"
dynamic loader into the behaviour you want by using versioned
symbols.

You can read more about versioned symbols here:
http://docs.sun.com/db/doc/806-0641/6j9vuqukc?a=view
http://www.linuxbase.org/spec/books...symversion.html

This:

>     ld -o program program.o -la1 -lb1

is a very bad idea (TM). On UNIX, you should not use 'ld' directly,
except under very rare circumstances. Use compiler driver ('cc',
'gcc', etc.) instead.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.





[ Post a follow-up to this message ]



    Re: A foo() in seperate .so's resolves to the wrong library  
Chuck Dillon


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-22-04 11:08 PM

Steven Reddie wrote:
>
> On Windows I get the behaviour that I need which is that since b1.so
> was shown that it could resolve foo() against b2.so it will only
> resolve it against that library at runtime.  I need this behaviour
> since a2.so and b2.so are actually different versions of the same
> library and the program must be able to simultaneouly use components
> which may use differerent versions of this library.
>

Your options will vary by platform but generally speaking you can't
pre-link a *NIX program to get the result you describe.  The closest
you can get is to dynamically link to at least one of the versions at
runtime.  See dlopen and the RTLD_LOCAL/GLOBAL discussion.

The idea would be to dlopen one (or both) of your .so with RTLD_LOCAL
asserted so that the symbols in that shared object doesn't polute your
program's namespace.  But this requires that you explicitly find the
functions your program needs to call using dlsym and references them
via pointers.

More specifically, you could create a stub layer around the API in
b1.so (call it b1stubs.so).  It would be a layer that mirrors the API
you need and lies between your program and b1.so.  The stub layer would
have stubs for each function/object you need in b1.so plus an
initialization function.  The initialization function of b1stubs.so
would dlopen the b1.so and use dlsym to get pointers to each
function/object.  References to somefunc()@b1stub.so would call
somefunc()b1.so via a pointer returned by dlsym(b1handle,"somefunc").
Since you would dlopen b1.so as RTLD_LOCAL b1.so and b2.so would have a
namespace separate from your program and so have their own foo().

Again, YMMV on different systems (e.g. Solaris, AIX, IRIX, ...).

HTH,

-- ced



--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.





[ Post a follow-up to this message ]



    Re: A foo() in seperate .so's resolves to the wrong library  
Frank Cusack


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-22-04 11:08 PM

On 20 Aug 2004 01:39:55 -0700 smr@essemer.com.au (Steven Reddie) wrote:
> Hi All,
>
> I've got a problem where I have two .so's that contain a function with
> the same name and the loader picks just one to be used for resolving
> all references.  I'm sure it's a common problem, but I'm having
> trouble explaining it, so a diagram:
>
> +-------------------+
> |      program      |
> +-------------------+
>     |            |
>     V            V
> +-------+    +-------+
> | a1.so |    | b1.so |
> +-------+    +-------+
>     |            |
>     V            V
> +-------+    +-------+
> | a2.so |    | b2.so |
> +-------+    +-------+
>
> a1.so and a2.so are two libraries of a particular component.  b1.so
> and b2.so are two libraries of a seperate independent component.
> a1.so and b1.so don't contain any clashing symbols.  a2.so and b2.so
> each have a function with the same name, let's say foo().  When a1.so
> was linked, the linker saw that it could resolve foo() against a2.so
> and flagged it as such.  When b1.so was linked, the linker saw that it
> could resolve foo() against b2.so and flagged it as such.  However,
> when linking a1.so and b1.so into program with a line such as (forget
> about the missing lib prefix):
>     ld -o program program.o -la1 -lb1
> the resulting executable when loaded resolves foo() against a2.so for
> both a1.so and b1.so.

On Solaris, try 'ld -B direct' when linking b1.

/fc





[ Post a follow-up to this message ]



    Re: A foo() in seperate .so's resolves to the wrong library  
Steven Reddie


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
08-23-04 01:01 PM

The dlopen/dlsym approach is what I was hoping to avoid as the API has
about 2500 functions.  I'm in the process of automating the creation
of the stubs which will be statically linked against (one function per
module to reduce aquired baggage).

The -Bgroup option on Solaris worked a treat, but the same option
which is documented as supported on Linux didn't work.  Anyway, I need
to target also AIX, HP-UX, DEC Unix and others in the future, so
something more common such as dlsym is required.

Thanks for the help.

Regards,

Steven





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 09:27 AM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register