символът не е намерен (ldd), но е там (nm)

Приложението ми се оплаква от символ, който не може да намери:

fatal: relocation error: file /foo/libxslt4c.so.113: symbol __1cDstdEcout_: referenced symbol not found (bar.c:1330)

И ldd казва същото:

ldd -d /bar/libxmllib.so
        libc.so.1 =>     /lib/sparcv9/libc.so.1
        [...]
        libxml4c.so.58 =>        /foo/libxml4c.so.58
        libxslt4c.so.113 =>      /foo/libxslt4c.so.113
        [...]
        /platform/SUNW,SPARC-Enterprise/lib/sparcv9/libc_psr.so.1
        /lib/sparcv9/../libm/sparcv9/libm_hwcap1.so.2
        symbol not found: __1cDstdEcout_                (/foo/libxslt4c.so.113)
        symbol not found: __1cDstdEcerr_                (/foo/libxslt4c.so.113)

Символът обаче е там - това казва nm:

nm /foo/libxslt4c.so.113.0 | grep __1cDstdEcerr_
[10915] |                   0|                   0|OBJT |GLOB |0    |UNDEF  |__1cDstdEcerr_

Но както можете да видите: Shndx=UNDEF. Какво означава това? Мислех, че ако нещо е недефинирано, то изобщо не е там. Но по някакъв начин е там, въпреки че приложението ми не може да го намери.

Система: Solaris 10 / UltraSPARC Моето приложение и всички библиотеки са 64-битови, /foo е в LD_LIBRARY_PATH_64 (/bar не е).

редактиране: Междувременно знам, че UNDEF е като "трябва да бъде разрешен в друга библиотека". И също така намерих библиотеката, която наистина има символа _1cDstdEcerr - това е libCstd.so, който е в /usr/lib. Или за да бъдем по-точни (тъй като имаме нужда от 64-битов вариант) /usr/lib/64. Така че е в един от пътищата за търсене на библиотеки по подразбиране на системата, които се показват от crle. Сега въпросът е: как символ може да не бъде разрешен, когато библиотеката, която го съдържа, е в пътя за търсене на системата?


person thorstenhirsch    schedule 18.02.2014    source източник
comment
Системата не търси всяка възможна библиотека в пътя на библиотеката за символи, а само тези, към които програмата или споделеният обект се свързват, както е посочено от elfdump -d /bar/libxmllib.so.   -  person alanc    schedule 19.02.2014


Отговори (1)


Предполага се, че не е решен, защото не сте го включили във вашите флагове за компилация, които са били предадени на линкера.

Ако имаше

LDFLAGS += -lCstd

във вашия Makefile, тогава трябваше да бъде предадено и линкерът щеше да направи правилното нещо (ако приемем, че използвате стандартните правила за компилиране, които добавят $(LDFLAGS) към вашия компилатор и извикване на линкер).

person James McPherson    schedule 18.02.2014
comment
Благодаря ви, но приложението ми всъщност е патентован софтуер от IBM. Разбира се, не съм сигурен за техните LDFLAGS, но съм почти сигурен, че са изградили софтуера правилно; проблемът е по-скоро моята среда на Solaris. - person thorstenhirsch; 19.02.2014
comment
Проблемът почти определено не е във вашата среда Solaris, а в начина, по който приложението е създадено. Можете да разгледате неудобно сложните вътрешни части на приложението, като използвате elfdump -d /path/to/application. Запис RUNPATH или RPATH ще ви помогне да разберете къде търси libCstd.so. Понякога (виждал съм това с лошо пакетиран GNU софтуер на Solaris) може да откриете, че пътеката за изпълнение е безсмислена. За щастие.... можете да използвате помощната програма elfedit, за да коригирате проблеми като този. Един от екипа за свързване на Solaris написа обширна публикация за инструмента, която е наистина полезна: goo.gl/RgxIy8 - person James McPherson; 19.02.2014
comment
Напълно си прав. IBM разреши проблема и ни изпрати нова библиотека. Благодаря ти много, Джеймс! - person thorstenhirsch; 03.03.2014