Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] Errore GLIBC_PRIVATE (librerie QT) dove è assente QTCreator

    ciao!

    ho creato un programma in Qt e funziona perfettamente sulle mie distro linux dove c'è qtcreator, e su window a 64bit (sia windows 7 che 10).
    il problema si presenta su altre adistro a 64bit dove non c'è installato qtcreator.

    ad esempio su xubuntu:
    codice:
    #!/bin/bash 
     
    LD_LIBRARY_PATH=$PWD/lib 
    export LD_LIBRARY_PATH 
     
    ./QImageResizing
    sul terminale mi esce questo errore:
    codice:
    ./QImageResizing: relocation error: /media/sf_Documenti/lib/libc.so.6: symbol __tunable_get_val, 
    version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
    avete qualche idea??
    magari sbaglio il modo con cui lanciare il programma dalla shell??

  2. #2
    La retrocompatibilità binaria su Linux è un disastro, non tanto per colpa del kernel ma per colpa di glibc.

    Se compili su una macchina moderna e vuoi ottenere un binario portabile dovresti linkare tutte le librerie staticamente (o comunque, portarti dietro tutte le librerie a cui fai riferimento); il problema è che questa cosa non si può fare per glibc, dato che contiene l'implementazione di diverse cose che dipendono dalla specifica configurazione macchina (ad esempio, diverse cose riguardanti il locale e la risoluzione dei DNS, così come il loader dinamico). Per farti un esempio, una volta per sbaglio abbiamo linkato staticamente glibc su una macchina Arch Linux e succedevano cose piuttosto strane su una macchina Ubuntu 16.04 (andava a cercare pezzi in percorsi che non esistevano).

    Viceversa, se anche lasci glibc come unica dipendenza dinamica (dato che non si può fare altrimenti), se compili su una macchina recente il tuo binario con ogni probabilità non girerà su una macchina con versioni più vecchie di glibc, dato che (1) vengono introdotti nuovi simboli e (2) glibc fa il versioning dei simboli. Molte funzioni di glibc non sono esportate semplicemente con il loro nome , ma con un nome versionato: quando fai riferimento a diverse funzioni di glibc (diciamo, memcpy) in realtà il tuo eseguibile si riferisce ad un simbolo versionato alla versione più recente fornita dalla glibc sul sistema su cui stai compilando (diciamo, GLIBC_2.2.5 memcpy). Se quindi anche il tuo eseguibile non usa funzioni introdotte in versioni nuove di glibc, probabilmente si romperà comunque perché fa riferimento a simboli già presenti su versioni vecchie, ma ad una versione più recente.

    Ancora peggio: glibc in realtà è scorporata in più pezzi, uno dei quali è il linker dinamico (il pezzo che serve a caricare i .so), e nel tuo caso stai facendo un peccato capitale: stai mischiando pezzi diversi di glibc.

    Nella tua directory lib ti sei tirato dietro libc.so.6 dalla macchina di build (cosa che non va fatta per gli stessi motivi per cui non bisogna linkare staticamente libc spiegati sopra), e la libc.so.6 "nuova" sta cercando di parlare con il loader di sistema (ld-linux-x86-64.so.2) vecchio. Il risultato è che si rompe tutto.

    ---

    La soluzione che uso di solito è buildare sempre tutto su una macchina con la distribuzione Linux più vecchia che si intende supportare (inteso come versione di glibc), possibilmente linkando tutto staticamente tranne libc.

    Se non si linka tutto staticamente, comunque conviene sempre portarsi dietro tutte le librerie tranne libc, onde evitare sorprese.

    La cosa funziona perché libc è normalmente backwards-compatibile - ovvero, la glibc nuova ha sempre dentro tutti i simboli forniti dalle glibc vecchie (grazie al versioning dei simboli), per cui su un sistema nuovo il tuo programma troverà sempre gli entrypoint che gli interessano.
    Ultima modifica di MItaly; 19-10-2017 a 14:16
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    ciao!

    intanto grazie per la risposta.
    a livello teorico ho capito il concetto, ma poi in pratica no.
    nel senso che ho provato a rinominare libc.so.6, e adesso ottengo questo errore:
    codice:
    $ ./start.sh 
    ./QImageResizing: /lib/x86_64-linux-gnu/libc.so.6: 
    version `GLIBC_2.25' not found (required by /media/sf_Documenti/QImageResize/lib/libsystemd.so.0)
    giustamente, in quanto lancio il programma da questa shell:
    codice:
    $ cat start.sh 
    #!/bin/bash 
     
    LD_LIBRARY_PATH=$PWD/lib 
    export LD_LIBRARY_PATH 
     
    ./QImageResizing
    però se lancio diretamente l'eseguibile, inizio ad avere problemi sulla mancanza delle altre dipendenze.
    in sostanza, a livello operativo, non ho capito come ne esco!

  4. #4
    È sempre lo stesso problema: ti sei tirato dietro delle librerie che dipendono dalla versione di glibc della macchina su cui hai effettuato la build, versione che (1) non ti puoi tirare dietro per i motivi sopra esposti e (2) non ti puoi non tirare dietro perché tutte le altre librerie dipendono dalla versione più recente di glibc, e non vanno con quella vecchia. Come ti ho detto, compila il tutto sulla più vecchia distribuzione che hai intenzione di supportare.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    ok, quindi nel caso specifico dovrei compilarlo su xubuntu.
    e poi provare il programma su una versione che ha glibc più nuova (che non deve essere ovviamente la mia distro).
    corretto??

    però c'è una cosa che mi lascia perplesso.
    alla fine stiamo parlando di xubuntu 17.10.
    possibile che contengano versioni così diverse di glibc??

    domani provo a vedere che versione c'è su xubuntu!

  6. #6
    in effetti ci sono versioni diverse.

    arch:
    codice:
    $ pacman -Qs glibc
    local/glibc 2.26-5 (base)
        GNU C Library
    xubuntu:
    codice:
    ~$ aptitude show libc6
    Pacchetto: libc6                                    
    Versione: 2.24-9ubuntu2.2
    Stato: installato
    Installato automaticamente: no
    Multi-Arch: same
    devo provare a fare come dici te!

  7. #7
    per la cronaca, in xubuntu ho fatto tutti gli aggiornamenti (me ne mancava qualcuno), e adesso c'è la stessa versione su arch.

    ho fatto una modifica alla shell di lancio:
    codice:
    #!/bin/bash 
     
    LD_LIBRARY_PATH=$PWD/lib 
    export LD_LIBRARY_PATH 
    
    QT_QPA_PLATFORM_PLUGIN_PATH=$PWD/plugins
    export QT_QPA_PLATFORM_PLUGIN_PATH
    
    ./QImageResizing
    adesso funziona tutto!

  8. #8
    I programmi scritti in freepascal non sono affetti da questo problema. Un programma compilato su un Debian datato funziona bene alche su uno recente.
    Per il resto è vero, la portabilità è disastrosa, problema che assolutamente non c'è con Windows.
    Come fanno a buildare virtualbox, libreoffice e programmi del genere? Non possono certo distribuire un compilato per ogni versione.

  9. #9
    Quote Originariamente inviata da denis76 Visualizza il messaggio
    I programmi scritti in freepascal non sono affetti da questo problema. Un programma compilato su un Debian datato funziona bene alche su uno recente.
    Per il resto è vero, la portabilità è disastrosa, problema che assolutamente non c'è con Windows.
    Come fanno a buildare virtualbox, libreoffice e programmi del genere? Non possono certo distribuire un compilato per ogni versione.
    tendenzialmente neanche su java, ad esempio, ci stanno questi problemi!

    cmq mi sono chiesto la stessa cosa....

  10. #10
    Quote Originariamente inviata da denis76 Visualizza il messaggio
    I programmi scritti in freepascal non sono affetti da questo problema. Un programma compilato su un Debian datato funziona bene alche su uno recente.
    Attenzione, anche qui funziona così, il datato va sul recente, ma non il contrario.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.