[geeks] Solaris linking issue

Francois Dion francois.dion at gmail.com
Fri Dec 5 09:43:57 CST 2008


On Fri, Dec 5, 2008 at 10:16 AM, Joshua Boyd <jdboyd at jdboyd.net> wrote:
> On Dec 5, 2008, at 7:44 AM, Francois Dion wrote:
>
>> On Fri, Dec 5, 2008 at 12:07 AM, Joshua Boyd <jdboyd at jdboyd.net> wrote:
>>>
>>> On Dec 3, 2008, at 5:31 PM, Joshua Boyd wrote:
>>>
>>>> I have a program that depends on ICU, a unicode library.  Solaris comes
>>>> with an older version (that is too old) of this library at /usr/lib.
>>>>  Before
>>>> realizing that (and it is too old anyway), I installed the latest
>>>> released
>>>> version in /usr/local/.
>>>>
>>>> Anyway, then I try to run my program, it gripes about not finding the
>>>> symbol ucol_close_4_0.  That symbol is found in
>>>> /usr/local/lib/libicui18n.so, but not in /usr/lib.
>>>>
>>>> So, I suspect that the run time linker is picking the older /usr/lib.
>>>>  How
>>>> do I force it to correct this without removing the old one(which I
>>>> suspect
>>>> is required elsewhere) or permanently changing crle since I only want
>>>> this
>>>> one program to use the new library?
>>>
>>> In the end, the issue turned out to be that the new build of ICU was
>>> 64bits
>>> while everything else was 32bits, including the Sun installed version.
>>>  Recompiling ICU as 32bits fixed the problem right up.
>>
>> That doesn't sound right. Everything is available in 32 and 64 bit
>> under Solaris 10. I've not had to deal with 32 bit only libs.
>>
>> /usr/lib/64/libicui18n.so -> ./libicui18n.so.3
>>
>> You have a different crle path for 64 bit:
>>
>> crle -64
>> vs
>> crle
>>
>> As for your original issue of hardwiring a lib, you use the -R option:
>> "Builds dynamic library search paths into the executable file."
>>
>> I've used it in the past, works as you would expect.
>
>
> You are forgetting that my complaint was that it was falling back to a
> preinstalled version that was too old rather than using the version that I
> built.
>
> The version of ICU that I built was compiled for 64bits while erlang and
> other libraries were only compiled for 32bits, so the linker went back to
> the old Sun installed 32bit version.

Ah, I was going to say, you'd get elf class errors at link time if
trying to mix. But, yes, if your application is 32 bit, then the stubs
are for the 32 bit versions of the libs.

It is really obvious if you ldd the application:

ldd my64bitapp
        libexpat.so.1 =>         /usr/lib/64/libexpat.so.1
        libsocket.so.1 =>        /lib/64/libsocket.so.1
        libnsl.so.1 =>   /lib/64/libnsl.so.1
...

ldd my32bitapp
        libexpat.so.0 =>         /usr/lib/libexpat.so.0
        libsocket.so.1 =>        /lib/libsocket.so.1
        libnsl.so.1 =>   /lib/libnsl.so.1
...

You can easily tell 32 vs 64.

Finally, to track what libraries are loaded dynamically at runtime,
yes you can do that under Solaris 10 with dtrace.

I had saved the following two scripts from Brian Cantrill, the first
was to set up a trigger for a specific dynamically loaded library (at
run time) and then fire off an actual script to execute against that
library. When calling trigger.d, pass it the pid of erlc and the
dynamic library you are interested in.

trigger.d:
#!/usr/sbin/dtrace -s

#pragma D option destructive
#pragma D option quiet

pid$1::dlopen:entry
/copyinstr(arg0) == $$2/
{
        stop();
        printf("Forking monitor for %s...\n", $$2);
        system("./monitor.d %d %s &", $1, $$2);
}

monitor.d:
#!/usr/sbin/dtrace -s

#pragma D option destructive
#pragma D option quiet


BEGIN
{
        system("prun %d", $1);
}

pid$1:$2::entry
{
        @[probefunc] = count();
}


In your case, you are interested in dynamic libraries loaded by that
specific lib, not a count.

Instead of the aggregation, you could display further dlopen:entry,
ie, off the top of my head, something like:

pid$1:$2:dlopen:entry
{
        printf("dynamic library loading: %s\n",copyinstr(arg0));
}

Of course it is all academic now since you got it working :)

Francois



More information about the geeks mailing list