PDA

Visualizza la versione completa : [C] Errore GLIBC_PRIVATE (librerie QT) dove è assente QTCreator


fermat
18-10-2017, 09:23
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:


#!/bin/bash

LD_LIBRARY_PATH=$PWD/lib
export LD_LIBRARY_PATH

./QImageResizing


sul terminale mi esce questo errore:


./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??

MItaly
19-10-2017, 14:12
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.

fermat
20-10-2017, 09:19
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:


$ ./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:


$ 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!

MItaly
21-10-2017, 14:47
È 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.

fermat
22-10-2017, 21:34
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!

fermat
23-10-2017, 12:39
in effetti ci sono versioni diverse.

arch:


$ pacman -Qs glibc
local/glibc 2.26-5 (base)
GNU C Library


xubuntu:


~$ 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!

fermat
24-10-2017, 14:44
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:


#!/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!
:ciauz:

denis76
02-11-2017, 11:59
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.

fermat
02-11-2017, 12:14
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....

MItaly
03-11-2017, 02:13
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.

Loading