Crunchez vos adresses URL
|
Rejoignez notre discord
|
Hébergez vos photos
Page 107 sur 107 PremièrePremière ... 7579799100101102103104105106107
Affichage des résultats 3 181 à 3 189 sur 3189
  1. #3181
    Bon, j'ai un problème qui me prends le chou aujourd'hui, j'ai besoin de l'aide des canard parce que j'ai beau fouillé j'y arrive pas.

    J'ai une librairie dynamique qui dépend d'une seconde librairie dynamique.

    Je charge cette seconde librairie dynamique avec dlopen et paf, je récupere un message d'erreur façon "undefined symbol : sem_post" ou "undefined symbol shm_unlink", ce genre de chose.

    Malheureusement ma science du fonctionnement des librairies dynamiques n'est plus ce qu'elle était.

    Normalement, si je ne me trompe pas, quand on charge une librairie avec dlopen on a absolument pas besoin de la charger à la compilation avec des "-lmalib", j'ai bon ?

    Ensuite, la question, c'est comment on peut utiliser une lib dynamique chargé ainsi avec une autre lib dynamique. Avant Ubuntu 20.04 ça marchait parfaitement mon bazare, mais maintenant je ne me souvient même plus comment ça marchait

    Prenons un exemple : j'utilise des fonction de la librairie mathématique dans lib1.so . J'utilise lib1.so dans lib2.so . A ce moment là lib1.so étant une lib dynamique il n'y a pas de lien entre lib2 et lib1 (si je fais ldd on ne trouve pas les noms lié). Quand je compile mon main.c j'ai beau faire ce que je veut, inclure -lm pour lui fournir les fonction mathématique ou quoi, la compilmation passe, mais à l’exécution il ne trouve pas les fonctions qui vont bien.
    Ce qui me parait normal à vrai dire, mais je ne sais plus comment c'est censé fonctionner bien

  2. #3182
    Ouais c'est la confusion entre Dynamic Linking et Dynamic Loading, là tu mélanges.

    On va prendre ce cas:
    App <- Lib1 <- Lib2

    Donc Lib2 est standalone, Lib1 dépend de Lib2 et App dépend de Lib1.

    Dans ce cas tu peux dlopen Lib1 dans App (dynamic loading) mais Lib1 doit (a priori) être linkée avec Lib2 (dynamic linking).

    Dans les deux cas c'est de la résolution de symbole au runtime mais les modalités sont un peu différente, en gros Dynamic Loading c'est le faire "manuellement".

    T'as un exemple complet là

    https://dwheeler.com/program-library...OWTO/x172.html

    (ou ici: https://tldp.org/HOWTO/html_single/C++-dlopen/)

    DL Library Example

    Here's an example from the man page of dlopen(3). This example loads the math library and prints the cosine of 2.0, and it checks for errors at every step (recommended):


    #include <stdlib.h>
    #include <stdio.h>
    #include <dlfcn.h>

    int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
    if (!handle) {
    fputs (dlerror(), stderr);
    exit(1);
    }

    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL) {
    fputs(error, stderr);
    exit(1);
    }

    printf ("%f\n", (*cosine)(2.0));
    dlclose(handle);
    }

    If this program were in a file named "foo.c", you would build the program with the following command:

    gcc -o foo foo.c -ldl
    Donc là on voit bien que la librairie n'est pas linkée à la compilation, mais loadée au runtime "manuellement", et très certainement que la lib dépend d'autres lib, a priori via du dynamic linking.

    ---

    Ensuite chainer du dynamic loading, c'est autre chose, a priori ça marche mais bon faudra bien loader les dépendances dans l'ordre etc.

    Important de noter que le Dynamic Loading en "temps normal" n'est quasiment jamais nécessaire, si tu dynamic link, tu peux hotswap tes librairies, pas durant le runtime mais tu peux juste stopper l'appli, hotswap la lib, et relancer.

    Le seul avantage du Dynamic Loading c'est la possibilité de hotswap durant le runtime, qui très honnêtement est un cas auquel il est très difficile de trouver un intérêt, tu gagnes extrêmement peu à faire ça, voire rien. Et charger des comportements dynamiques au runtime ça s'appelle...: programmer une application!

    Donc je te conseille de toujours rester sur du Dynamic Linking, c'est bien plus solide.

  3. #3183
    Citation Envoyé par Kamikaze Voir le message
    [...]

    Le seul avantage du Dynamic Loading c'est la possibilité de hotswap durant le runtime, qui très honnêtement est un cas auquel il est très difficile de trouver un intérêt, tu gagnes extrêmement peu à faire ça, voire rien. Et charger des comportements dynamiques au runtime ça s'appelle...: programmer une application!

    Donc je te conseille de toujours rester sur du Dynamic Linking, c'est bien plus solide.
    Globalement très d'accord, et j'ajouterai que le Dynamic Loading peut être aussi souvent utilisé dans les mécanismes de plugins (sans pour autant utiliser la possibilité de les recharger plusieurs fois pendant la vie de l'application).
    Dernière modification par Mr Slurp ; 25/09/2020 à 17h53.
    La programmation est une course entre le développeur, qui s’efforce de produire des applications à l’épreuve des imbéciles, et l’univers qui s’efforce de produire de meilleurs imbéciles... L’univers a une bonne longueur d’avance !!!

  4. #3184
    Citation Envoyé par Kamikaze Voir le message
    Ouais c'est la confusion entre Dynamic Linking et Dynamic Loading, là tu mélanges.

    On va prendre ce cas:
    App <- Lib1 <- Lib2

    Donc Lib2 est standalone, Lib1 dépend de Lib2 et App dépend de Lib1.

    Dans ce cas tu peux dlopen Lib1 dans App (dynamic loading) mais Lib1 doit (a priori) être linkée avec Lib2 (dynamic linking).

    Dans les deux cas c'est de la résolution de symbole au runtime mais les modalités sont un peu différente, en gros Dynamic Loading c'est le faire "manuellement".

    T'as un exemple complet là

    https://dwheeler.com/program-library...OWTO/x172.html

    (ou ici: https://tldp.org/HOWTO/html_single/C++-dlopen/)



    Donc là on voit bien que la librairie n'est pas linkée à la compilation, mais loadée au runtime "manuellement", et très certainement que la lib dépend d'autres lib, a priori via du dynamic linking.

    ---

    Ensuite chainer du dynamic loading, c'est autre chose, a priori ça marche mais bon faudra bien loader les dépendances dans l'ordre etc.

    Important de noter que le Dynamic Loading en "temps normal" n'est quasiment jamais nécessaire, si tu dynamic link, tu peux hotswap tes librairies, pas durant le runtime mais tu peux juste stopper l'appli, hotswap la lib, et relancer.

    Le seul avantage du Dynamic Loading c'est la possibilité de hotswap durant le runtime, qui très honnêtement est un cas auquel il est très difficile de trouver un intérêt, tu gagnes extrêmement peu à faire ça, voire rien. Et charger des comportements dynamiques au runtime ça s'appelle...: programmer une application!

    Donc je te conseille de toujours rester sur du Dynamic Linking, c'est bien plus solide.
    Ok merci pour les éclaircissement.
    En fait j'ai fini par trouver ce qui n'allez pas. La "lib2" dans ton exemple dépendaient de pthread et ltr, mais ce n'était pas indiqué à la création de la librairie. Sauf qu'en fait il faut que ça le soit au linkage lorsqu'on créé la librairie lib2 pour que lib 1 puisse gérer la chose et que le App comprenne ce qu'il se passe.

    Maintenant la grande question c'est : pourquoi ce programme fonctionnait parfaitement sous Ubuntu 16 et ne fonctionne plus sous Ubutu 20 (gcc 10) . ... il y a eu un changement autour de pthread et ltr ?

    Bon sinon je crois que l’intérêt ici c'était, dans l'idée d'avoir une appli qui ne charge que le minimum, c'est une appli qui fonctionne en lisant des script qui lancent des sous parties de code C (des "boites") et selon le script on a pas besoin de toutes les boites.
    C'était l'idée à la base, mais en vrai on l'utilise pas trop donc c'est un peu obsolète... (mais je peut pas vraiment changer ça aisément).

    Le but c'était, je pense, de pouvoir avoir un exécutable très petit accompagné juste des .so nécessaire en fonction du script utilisé à cet instant précis. Pour faire de l'embarqué notamment. (oui parce qu'il y a beaucoup de boites, donc ça économise des tonnes de codes).
    Mais avec l'évolution du matériel un exécutable de plusieurs mo ne pose plus vraiment de soucis, même en embarqué.

  5. #3185
    Généralement la pratique c'est de faire du Static Linking pour de l'embarqué. Le truc c'est que le Dynamic Loading n'affecte que la mémoire vive grosso merdo, sur le disque ça prendra la même place, donc l'argument embarqué n'est pas vraiment pertinent, d'autant plus que même avec du Dynamic Linking le truc n'est pas complètement idiot, puis bon ces considérations de "mémoire vive" c'est plus dans le programme lui même, tu gères ta mémoire comme tu veux, sans oublier le paging , y'a plein de systèmes embarqués sans cette distinction mémoire vive vs disque, etc.

    Mais bref on s'éloigne.

    Pour ton problème faudrait que tu redécrives tout à plat, j'arrive pas à suivre tes dépendances exactes. Regarde le code, si y'a une référence à un header, faudra le fournir à la compilation, si c'est du dlopen c'est dynamic loading mais il faudra que le truc loadé fonctionne déjà en standalone, donc qu'il compile et qu'il run en premier lieu.

    Honnêtement si tu poses tout à plat t'es garanti de réussir à faire tourner ton truc, surtout si c'est du C.

    Là je comprends pas si t'essayes de bouger les binaires d'une machine à l'autre, ou autre chose, s'pas clair, c'est la même famille de processeur au moins? Si tu compiles un truc sur du X86 t'sais ça tournera pas sur de l'ARM (bon là ça foire à la résolution de symbole mais s'pour l'exemple)?

    Si tu recompiles tout sur une nouvelle machine c'est garanti que ça fonctionne, si y'a eu une update de pthread qui brise la compatibilité (m'étonnerait mais bon) ça pétera à la compilation et tu verras l'erreur directement.

    En résumé: décris correctement tes dépendances, compile tes trucs dans l'ordre sur la nouvelle machine, du moins dépendant au plus dépendant, si ça casse tu répares.

    Ensuite exécute le bazar et ça devrait être bon, si à l'exécution ça foire je serai surpris.

    En regardant vite fait on dirait qu'il est possible que pthread ait changé d'une version à l'autre. pthread ça veut dire POSIX thread, donc c'est juste une spécification, implémentée différemment selon chaque OS qui est POSIX compliant.

    Donc ouais tu peux pas forcément juste bouger ton binaire, si c'est ce que tu as fait (après je suis pas un expert concernant les garanties de compatibilité qu'ils offrent, perso j'utilise toujours un niveau d'abstraction genre cmake ou autre, et je me soucis pas de ça).

    Ubuntu 16, z'ont ça:
    libc6-dev (2.23-0ubuntu11.2)
    GNU C Library: Development Libraries and Header Files

    Ubuntu 20:
    libc6-dev (2.31-0ubuntu9)
    GNU C Library: Development Libraries and Header Files

    D'après ce thread libc est backward compatible donc je doute qu'on soit sur la bonne voie:

    https://stackoverflow.com/questions/...sions-of-glibc

    ---

    Là ce que j'ai compris c'est

    Lib2 standalone (juste des dépendances système quoi), linkée à Lib1, et l'App dynamic load Lib1 ?

    Donc là il faudrait compiler Lib2, compiler Lib1, compiler l'App puis la lancer.
    Dernière modification par Kamikaze ; 26/09/2020 à 09h11.

  6. #3186
    Citation Envoyé par Kamikaze Voir le message
    Généralement la pratique c'est de faire du Static Linking pour de l'embarqué. Le truc c'est que le Dynamic Loading n'affecte que la mémoire vive grosso merdo, sur le disque ça prendra la même place, donc l'argument embarqué n'est pas vraiment pertinent, d'autant plus que même avec du Dynamic Linking le truc n'est pas complètement idiot, puis bon ces considérations de "mémoire vive" c'est plus dans le programme lui même, tu gères ta mémoire comme tu veux, sans oublier le paging , y'a plein de systèmes embarqués sans cette distinction mémoire vive vs disque, etc.
    Ouais, je sais pas trop l'objectif de l'époque mais c'est comme ça maintenant et j'ai pas vraiment le temps de le retravailler.

    Citation Envoyé par Kamikaze Voir le message
    ...
    Pour le reste le cas précis c'est ça :


    Lib2 :
    C'est la librairie en bout de chaine, elle utilise des fonctions de pthread (sem_post etc.) et ltr (shm_xxx).
    Depuis 1990 que ce programme existe ( ) le programme était compilé très simplement SANS préciser la dépendance à pthread et ltr. En gros c'était un linkage très simple de quelques caractères. (gcc les .o et pif fait le .so)

    Lib1 :
    C'est une librairie qui utilise Lib2 via un linkage dynamique : en gros c'est simplement compilé avec gcc blabla -lLib2 et voila c'est tout et dans la Lib1 on inclut les h de lib2 et on utilise les fonctions de Lib2 et tout marche bien.

    App :
    C'est une app qui charge Lib1 en faisant un dlopen. De 1990 à 2020, sans changement de notre part, ça marchait parfaitement et là paf : unresolved symbol sur sem_post et cie (les symboles venant de la Lib2 via la Lib1)

    Au final j'ai résolu le problème en précisant explicitement à la création de Lib2 qu'il y avait pthread (-pthread) et ltr (-ltr). Et là paf, tout marche.

    Mais pourquoi tout marche maintenant et pas avant, c'est un mystere. Et je confirme que c'est bien QUE sous Ubuntu 20 et gcc 10, puisque j'ai relancé la compilation puis l'execution sur un Ubuntu 16 et ça marchait parfaitement.
    Note que tu peut simplifier grandement le problème si tu veut, sans que ça ne change le problème de fond, puisque j'ai fait un programme test qui charge Lib2 directement en dlopen depuis App et que c'était exactement le même bug. Donc ce n'est pas le chainage le soucis, c'est vraiment le dlopen de Lib2 qui pose problème.

    Sinon pour tes question : on compile toujours le programme en local dans notre cas, même sur embarqué. Comme ça aucun problème.

    Donc ici je parle bien du cas 1 qui marche :
    - compilation sous Ubuntu 16 puis lancement sous Ubuntu 16

    et du cas 2 qui ne marche pas :
    - compilation sous Ubuntu 20 (gcc 10) et lancement sous ubuntu 20.

    Le unresolved symbol était toujours au lancement, aucun problème à la compilation de lib 2, lib1 et app dans les deux cas.
    Alors pourquoi faut-il préciser pthread et ltr de manière exhaustive maintenant, c'est un grand mystère. Et en soit c'est assez chelou. J'avais enregistrer pour ma part que ça ne servait à rien de précise les dépendance à la création d'une librairie mais qu'il fallait plutot les redonner au programme final ...

  7. #3187
    Pas de changements des autres dépendances de ton application ? Peut-être qu'un de ces dépendances préchargeait libpthread et librt pour toi.

  8. #3188
    Ouais a priori pthread et consors étaient linkés silencieusement, possible selon le compilo ou autre (chaines de dépendances, du coup system specific). Il faut toujours linker pthread explicitement de manière générale, ou quelque dépendance que ce soit (faut bien un moyen de résolution)

    J'ai trouvé une histoire similaire ici: https://gcc.gnu.org/legacy-ml/gcc-he.../msg00263.html

  9. #3189
    Citation Envoyé par Cwningen Voir le message
    Pas de changements des autres dépendances de ton application ? Peut-être qu'un de ces dépendances préchargeait libpthread et librt pour toi.
    Nop comme je l'ai précisé, j'ai fait ctrl-c ctrl-v de l'appli sur un Ubuntu 16 et ça a compilé alors que ça ne fonctionnait pas sous Ubuntu 20 + gcc 10

    - - - Mise à jour - - -

    Citation Envoyé par Kamikaze Voir le message
    Ouais a priori pthread et consors étaient linkés silencieusement, possible selon le compilo ou autre (chaines de dépendances, du coup system specific). Il faut toujours linker pthread explicitement de manière générale, ou quelque dépendance que ce soit (faut bien un moyen de résolution)

    J'ai trouvé une histoire similaire ici: https://gcc.gnu.org/legacy-ml/gcc-he.../msg00263.html
    OK, c'est quand même surprenant ce changement "silencieux" sur les versions récentes, j'ai rien trouvé de spécial de mon coté
    Enfin bon, quoi qu'il en soit ça fonctionne ...

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •