chargement libgiac impossible dans OOo

Librairie C++ de calcul formel/ C++ symbolic computation library

Modérateur : xcasadmin

Répondre
cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

chargement libgiac impossible dans OOo

Message par cdeval » mar. avr. 27, 2010 5:36 pm

Salut,
j'avance sur ce problème.
Petit rappel : ma compil libgiac en 64 bits ne veut pas se charger dans mon extension alors que ta compil passe bien. la commande ldd ne fait pas apparaître de librairie manquante pourtant ça ne passe pas.
Je me suis attaqué au mammouth OOo. J'ai recompilé le module qui charge la librairie via la commande dlopen() et j'y ai ajouté le code :

Code : Tout sélectionner

		if (pLib == 0) {
			printf("******** Error osl_loadModule: %s\n", dlerror());
			printf("******** Nom du module : %s\n",pszModuleName);
		}

car OOo ne remonte pas dlerror() dans la fenêtre d'erreur.
Maintenant j'en sais plus, voilà le message que j'obtiens :

Code : Tout sélectionner

*** Ouverture du module : /home/chris/.openoffice.org/3/user/uno_packages/cache/uno_packages/Nfgrpn_/CmathOOoCAS.oxt/Linux_x86_64/CmathOOoCAS.uno.so
*** pLib = 0
******** Error osl_loadModule: /home/chris/.openoffice.org/3/user/uno_packages/cache/uno_packages/Nfgrpn_/CmathOOoCAS.oxt/Linux_x86_64/libgiac.so.0: undefined symbol: _ZNSt3tr18__detail12__prime_listE
******** Nom du module : /home/chris/.openoffice.org/3/user/uno_packages/cache/uno_packages/Nfgrpn_/CmathOOoCAS.oxt/Linux_x86_64/CmathOOoCAS.uno.so
Si ça t'inspire....

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: chargement libgiac impossible dans OOo

Message par parisse » mar. avr. 27, 2010 6:49 pm

curieux, je ne trouve pas ce symbole dans libgiac.so.0 sur ma machine 64 bits... du coup je ne vois pas comment t'aider

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » mar. avr. 27, 2010 7:54 pm

ok, étrange.
Le problème semble bien lié à l'ouverture de la librairie avec dlopen() puisque xcas et mon programme en c n'ont aucun soucis pour utiliser la libgiac que j'ai compilée.
je viens de tomber là dessus : http://linuxfr.org/forums/20/8481.html. Ca pourrait être une piste car il semble bien que ce soit le type de compilation qui compte et pas l'environnement.
Utilises-tu ce genre d'options pour compiler : -rdynamics ou -Wl,--export-dynamic ?

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » mar. avr. 27, 2010 8:10 pm

je pense que je me rapproche de la source du problème.
Le code qui charge ma librairie est :

Code : Tout sélectionner

oslModule SAL_CALL osl_psz_loadModule(const sal_Char *pszModuleName, sal_Int32 nRtldMode)
{
    OSL_ASSERT(
        (nRtldMode & SAL_LOADMODULE_LAZY) == 0 ||
        (nRtldMode & SAL_LOADMODULE_NOW) == 0); /* only either LAZY or NOW */
	if (pszModuleName)
	{
#ifndef NO_DL_FUNCTIONS
        int rtld_mode =
            ((nRtldMode & SAL_LOADMODULE_NOW) ? RTLD_NOW : RTLD_LAZY) |
            ((nRtldMode & SAL_LOADMODULE_GLOBAL) ? RTLD_GLOBAL : RTLD_LOCAL);
		void* pLib = dlopen(pszModuleName, rtld_mode);

#if OSL_DEBUG_LEVEL > 1
		if (pLib == 0) {
			OSL_TRACE("*** Error osl_loadModule: %s\n", dlerror());
			OSL_TRACE("*** Nom du module : %s\n",pszModuleName);
		}
#endif /* OSL_DEBUG_LEVEL */
		printf("*** Ouverture du module : %s\n",pszModuleName);
		printf("*** pLib = %i\n",pLib);
		if (pLib == 0) {
			printf("******** Error osl_loadModule: %s\n", dlerror());
			printf("******** Nom du module : %s\n",pszModuleName);
		}
		return ((oslModule)(pLib));
#else   /* NO_DL_FUNCTIONS */
		printf("No DL Functions\n");
#endif  /* NO_DL_FUNCTIONS */
	}
	return NULL;
}
et j'ai trouvé ça :
In dlopen(), the value of flag must be either RTLD_LAZY, meaning ``resolve undefined symbols as code from the dynamic library is executed'', or RTLD_NOW, meaning ``resolve all undefined symbols before dlopen() returns and fail if this cannot be done''. RTLD_GLOBAL may be optionally or'ed with either value in flag, meaning that the external symbols defined in the library will be made available to subsequently loaded libraries. While you're debugging, you'll probably want to use RTLD_NOW; using RTLD_LAZY can create inscrutable errors if there are unresolved references. Using RTLD_NOW makes opening the library take slightly longer (but it speeds up lookups later); if this causes a user interface problem you can switch to RTLD_LAZY later.
et cà :
man dlopen :

Les références externes de la bibliothèque sont résolues en utilisant
les bibliothèqujes mentionnées dans sa liste de dépendances, et toutes
les autres bibliothèques éventuellement ouvertes auparavant avec
l'attribut RTLD_GLOBAL. Si l'édition des liens de l'exécutable a été
faite avec l'option "-rdynamic", alors ses symboles globaux seront
également employés pour résoudre les références de la bibliothèque
chargée dynamiquement.
cela pourrait expliquer que ce symbole appartienne à une autre librairie et que tu ne le connaisse pas ?
J'essaierai une recompilation avec -rdynamic
A+

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » lun. mai 03, 2010 12:58 pm

Salut Bernard,

après avoir lu pas mal de documentation et recompilé maintes fois la libgiac, je n'ai toujours pas de réponse !

Je te fais un résumé :
1) je pensais vraiment qu'il fallait une option de compilation spéciale sur mon AMD64 pour que libgiac soit ouvrable par dlopen(). D'après la doc libtoll (http://www.gnu.org/software/libtool/man ... ed-modules):
If symbols from your executable are needed to satisfy unresolved references in a library you want to dlopen you will have to use the flag -export-dynamic. You should use -export-dynamic while linking the executable that calls dlopen:
burger$ libtool --mode=link gcc -export-dynamic -o helldl main.o
burger$
mais ça ne marche pas mieux. J'ai essayé aussi de faire l'édition des liens directement avec ld + diverses options mais pas mieux.

2) j'ai essayé de voir si c'était mieux en 32bits et j'obtiens le même problème : ma compilation de libgiac ne passe pas dans OOo !

3) j'ai alors essayé de compiler ma librairie en faisant l'édition des liens à partir de libgiac.a en me disant que je n'aurais pas symbole non résolus mias j'obtiens une erreur :
/usr/bin/ld: libgiac.a(ti89.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
libgiac.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
J'ai alors tenté la même manip en 32 bits et ça passe, j'obtiens bien ma librairie CmathOOoCAS.uno.so qui fait 25Mo au lieu de 255Ko mais toujours refusé par dlopen()

4) j'ai essayé sur mon eeepc ubuntu 10.04. J'ai compilé libgiac et mis dans OOo : ça passe ! Je commençais à croire que c'est moi qui portait la poisse !

5) Les 2 Linux sur lesquels ça ne passe pas sont en fait la même machine : un AMD64 (le 32 bits est en virtualbox). Je ne soupçonne plus vraiment un pb libtool puisque tes compils ne tiennent pas compte de cela je suppose mais j'ai vraiement l'impression que c'est ma compil avec l'amd64 qui fait planter. En cherchant sur google, je suis tombé là : http://www.gentoo.org/proj/en/base/amd6 ... #doc_chap7 sur :
Case 3: Lack of `-fPIC' flag in the software to be built

This is the most common case. It is a real bug in the build system and should be fixed in the ebuild, preferably with a patch that is sent upstream. Assuming the error message looks like this:

Code Listing 6.1: A sample error message

.libs/assert.o: relocation R_X86_64_32 against `a local symbol' can not be used
when making a shared object; recompile with -fPIC .libs/assert.o: could not
read symbols: Bad value
c'est le genre d'erreur que j'obtiens en essayant de compiler à partir de libgiac statique.
J'ai regardé si tout était compilé avec -fPIC et ça l'est , aussi bien dans libgiac que dans ma librairie.
D'ailleurs, j'ai vu que le makefile fourni pour OOo inclu -fPIC pour la version 64 bits alors qu'il n'y est pas
en 32 bits. Cette option semble bien indispensable sur amd64.

Avec quel processeur compiles-tu en 64 bits ?

6) je viens de recompiler avec ./configure --disable-ntl mais à part une plus grosse libgiac, ça ne passe toujours pas dans OOo.

Pour conclure, je ne pense pas que mon problème soit lié au degré de statisticité de libgiac (toutes les dépendances sont satisfaites à chaque fois) mais plutôt à la façon de faire l'édition des liens sur mon amd64. Et dlopen() vérifie tout à l'ouverture visiblement. Peut-être même que la libgiac que je compile fonctionne avec xcas jusqu'au moment ou je ferai appel à une fonction dont le symbole ne sera pas résolu dans ma libgiac....
Au passage, j'ai vu que le symbole non résolu à l'ouverture avec dlopen() (fonction prime_list()) pourrait appartenir à la libpari...
Voilà, je ne sais plus trop quoi tester maintenant, même s'il n'y a pas péril en la demeure.... c'est juste que j'aimerais savoir ce qui se passe. L'important c'est que tes libgiac à toi ne posent aucun problème....
Si tu as une idée, je suis preneur.
A+

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: chargement libgiac impossible dans OOo

Message par parisse » lun. mai 03, 2010 2:02 pm

c'est bien mysterieux tout ca. Je compile en utilisant les outils de creation de package debian, sur un Intel Xeon en utilisant le script mkdebian2.
Peut-etre que tu pourrais essayer de generer un package debian et voir si le probleme persiste.

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » lun. mai 03, 2010 8:05 pm

ok je vais essayer de générer un package debian.

En attendant je continue le jeu de piste : j'ai regardé avec "nm -C" les symbols de ma libgiac qui fait planter dlopen. Voilà entre deux fonctions le symbole qui ne lui plait pas (prime_list) :

Code : Tout sélectionner

000000000014a600 W std::tr1::unordered_map<unsigned long long, long long, giac::hash_function_unsigned_object, std::equal_to<unsigned long long>, std::allocator<std::pair<unsigned long long const, long long> > >::~unordered_map()
                 U std::tr1::__detail::__prime_list
0000000000154650 W std::tr1::__detail::_Map_base<std::vector<int, std::allocator<int> >, std::pair<std::vector<int, std::allocator<int> > const, giac::gen>, std::_Select1st<std::pair<std::vector<int, std::allocator<int> > const, giac::gen> >, true, std::tr1::_Hashtable<std::vector<int, std::allocator<int> >, std::pair<std::vector<int, std::allocator<int> > const, giac::gen>, std::allocator<std::pair<std::vector<int, std::allocator<int> > const, giac::gen> >, std::_Select1st<std::pair<std::vector<int, std::allocator<int> > const, giac::gen> >, std::equal_to<std::vector<int, std::allocator<int> > >, giac::hash_function_object, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, false, true> >::operator[](std::vector<int, std::allocator<int> > const&)
dans ta libgiac, prime_list n'existe pas. Je pensais tenir une piste mais en regardant la libgiac que j'ai compilée sur mon eeepc et qui fonctionne dans OOo, je l'ai aussi dans la liste des symbols avec le même "U" et pas d'adresse. Et elle ne fait pas planter dlopen !
Fausse piste a priori.

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » lun. mai 03, 2010 9:06 pm

je pense avoir trouvé !
pour que libgiac soit "dlopen-able" j'ai ajouté "-ldl" à l'édition des liens et plus de problème sur linux64. J'ai donc tapé simplement dans src :

Code : Tout sélectionner

gcc -shared  -ldl sym2poly.lo gausspol.lo threaded.lo moyal.lo maple.lo ti89.lo mathml.lo misc.lo permu.lo quater.lo desolve.lo input_parser.lo symbolic.lo index.lo modpoly.lo modfactor.lo ezgcd.lo derive.lo solve.lo intg.lo intgab.lo risch.lo lin.lo series.lo subst.lo vecteur.lo csturm.lo tex.lo global.lo ifactor.lo alg_ext.lo gauss.lo isom.lo plot.lo plot3d.lo help.lo rpn.lo prog.lo pari.lo cocoa.lo unary.lo usual.lo identificateur.lo gen.lo input_lexer.lo first.lo TmpLESystemSolver.lo TmpFGLM.lo  -lmpfr -lpthread -lpari -lfltk_images -ljpeg -lpng -lz -lfltk -lfltk_gl -lXext -lXft -lfontconfig -lXinerama -lGL -lgsl -lgslcblas -lreadline -lncurses -ldl -lm -lX11 -lXext -lgmp -lc  -Wl,-soname -Wl,libgiac.so.0 -o .libs/libgiac.so.0.0.0
puis j'ai mis cette libgiac dans mon extension et plus de problème à l'ouverture dans OOo :D :D :D

je testerai demain soir sur mon linux32 en virtualbox sur amd64 pour voir si ça résout aussi le problème.
j'arrête pour ce soir...
A+

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: chargement libgiac impossible dans OOo

Message par parisse » mar. mai 04, 2010 6:58 am

c'est bizarre quand meme, parce que configure teste la presence de la libdl et de dlopen, tu devrais avoir #define HAVE_LIBDL 1 dans config.h sans rien faire.

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » mar. mai 04, 2010 11:39 pm

Oui, j'ai bien HAVE_LIBDL 1 dans config.h.
D'ailleurs, le "-ldl" était bien présent dans l'édition des liens avant que je n'en remette un en plus.
Donc ce n'était pas l'origine du problème. Je ne sais pas comment cela a pu fonctionner hier car aujourd'hui la même libgiac ne passe plus !!!!

Mais cette fois je crois avoir trouvé pour de bon :
j'ai découvert que le symbol qui bloque dlopen() fait partie de libstdc++.so.6 :

Code : Tout sélectionner

GLIBCXX_3.4.10 {
    _ZNSt3tr18__detail12__prime_listE;
etc...
pourtant sur mon pc j'ai bien cette GLIBCXX :

Code : Tout sélectionner

strings /usr/lib/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
MAIS, openoffice fournit aussi une version de libstdc plus ancienne :

Code : Tout sélectionner

strings /opt/openoffice.org/ure/lib/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_FORCE_NEW
et cette version s'arrête justement avant la 3.4.10, celle qui contient la fameuse prime_list qui bloque dlopen. J'ai donc supprimé la libstdc de OOo pour l'obliger à aller chercher celle de usr/lib et mon extension passe sans problème, plus de blocage à dlopen. :D <- cette fois pour de bon !

Pour expliquer que tes libgiac passent sur mon système, je pense que ton gcc repose sur une libstdc plus ancienne que la mienne et qu'il doit s'arrêter aussi avant la GLIBCXX_3.4.10 ce qui fait que ta libgiac ne contient pas le fameux symbol qui bloquait (ça je l'avais déjà constaté avec nm sur ta libgiac).
Pour ma part j'ai gcc et libstdc notés en version 4.4.1 dans synaptic.
Je pense que si tu mettais à jour ton système 32bit et 64bit, je me serais retrouvé avec des libgiac qui contiendraient comme moi le symbol prime_list non contenu dans le stdlibc de OOo et que j'aurais été bien bloqué.

J'espère cette fois que tout se tient et que je vais pouvoir clore définitivement cette tracasserie.
Peux-tu me confirmer que la libstdc de tes systèmes qui te servent à compiler ne contiennent pas mieux que GLIBCXX_3.4.9 ?

parisse
Messages : 5743
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: chargement libgiac impossible dans OOo

Message par parisse » mer. mai 05, 2010 6:51 am

oui, c'est certainement ca, il doit linker les symboles de la libc demandes par libgiac avec la libc d'openoffice. Effectivement, les systemes sur lesquels je compile sont plutot anciens, par exemple en 32 bits
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_FORCE_NEW
Bien vu!!

cdeval
Messages : 192
Inscription : mer. juin 03, 2009 4:28 pm

Re: chargement libgiac impossible dans OOo

Message par cdeval » mer. mai 05, 2010 1:01 pm

Je viens de tester aussi sur mon linux32 bits qui possède aussi une libgcc_s.so.1 et une libstdc++.so.6 plus récentes que celles fournies par OOo et ça marche parfaitement en renommant ces deux librairies de OOo pour que le système prennent celles de usr/lib.
Ainsi plus de symbols non résolus avec dlopen.

En parcourant google, je me suis rendu compte que certains se demandaient pourquoi OOo continuait à fournir ces deux librairies dans leur distrib surtout qu'elles sont plutôt vieilles et qu'elles posent des pb pour les add-in sous forme de librairies (enfin il faut dire que ça court pas les rues, les extensions OOo en C++ doivent se compter sur les doigts d'une main ! la plupart sont plutôt en java)
J'ai regardé sur mon eeepc passé en ubuntu 10.04 et le OOo n'est pas celui du site OOo mais un package ubuntu pour une meilleur intégration avec gnome. Et bien dans cette distrib, ces deux librairies sont inexistantes ! Donc aucune manip à faire pour installer mon extension avec une libgiac compilée sur mon PC.

J'ai essayé de regarder s'il était possible de recompiler pour utiliser une version plus ancienne de libstdc mais je n'ai rien trouvé qui me semble simple.
Je vais quand même poster sur la liste de diffusion OOo pour leur expliquer la gêne.

Bref, je crois que le sujet est clos, l'explication est trouvée et tant que j'utilise tes libgiac compilées sur tes PC non à jour :wink:, les lib OOo seront en avance sur les tiennes et je n'aurai pas de problème !
A+

Répondre