View Full Version : [C++] Strano errore del linker a run-time
Ciao a tutti!
So che è una domanda molto specifica e particolare, ma non so più come risolvere questo problema, spero che qualcuno abbia qualche idea in merito!!!
Sto scrivendo un programma in C++ usando le librerie multipiattaforma Qt4.
In particolare devo leggere dei files XML e ho fatto un sistema a plugin che permette di scegliere il parse XML a run-time.
Per adesso ho scritto 2 plugin, uno che usa Xerces-c (il parser XML del progetto apache) e uno che usa QtXml (un modulo delle Qt4).
Quando l'esecuzione arriva su una particolare riga del programma ricevo un errore ed il programma esce (senza andare in crash).
La cosa strana è che l'errore esce solo se arrivo in quel punto facendo una particolare sequenza di operazioni, in tutti gli altri casi funziona benissimo!
L'errore è:
my_program: symbol lookup error: libqtxml_plugin.so: undefined symbol: _ZN15QXmlInputSourceC1EP9QIODevice
Sto programmando su una Debian testing: ho provato su Windows 2000 e su una Slackware e il problema non si presenta.
Su Windows ho compilato con MinGW e sulla Slacware con una versione più vecchia di GCC di quella che ho sulla mia Debian, può essere un problema del nuovo GCC?
Non so dove cercare perché il codice apparentemente funziona bene e non andando in crash anche il debugger non mi da informazioni.
Qualcuno ha qualche idea in merito?
OS:
Linux Debian testing
Compilatore:
gcc (GCC) 4.1.3 20070601 (prerelease) (Debian 4.1.2-12)
CPU:
AMD AthlonXP 2200+
Kernel:
2.6.18-4-k7
Ma la versione delle librerie è la stessa ?
trallallero
08-07-2007, 08:43
Ciao a tutti!
So che è una domanda molto specifica e particolare, ma non so più come risolvere questo problema, spero che qualcuno abbia qualche idea in merito!!!
Sto scrivendo un programma in C++ usando le librerie multipiattaforma Qt4.
In particolare devo leggere dei files XML e ho fatto un sistema a plugin che permette di scegliere il parse XML a run-time.
Per adesso ho scritto 2 plugin, uno che usa Xerces-c (il parser XML del progetto apache) e uno che usa QtXml (un modulo delle Qt4).
Quando l'esecuzione arriva su una particolare riga del programma ricevo un errore ed il programma esce (senza andare in crash).
La cosa strana è che l'errore esce solo se arrivo in quel punto facendo una particolare sequenza di operazioni, in tutti gli altri casi funziona benissimo!
L'errore è:
my_program: symbol lookup error: libqtxml_plugin.so: undefined symbol: _ZN15QXmlInputSourceC1EP9QIODevice
Sto programmando su una Debian testing: ho provato su Windows 2000 e su una Slackware e il problema non si presenta.
Su Windows ho compilato con MinGW e sulla Slacware con una versione più vecchia di GCC di quella che ho sulla mia Debian, può essere un problema del nuovo GCC?
Non so dove cercare perché il codice apparentemente funziona bene e non andando in crash anche il debugger non mi da informazioni.
Qualcuno ha qualche idea in merito?
OS:
Linux Debian testing
Compilatore:
gcc (GCC) 4.1.3 20070601 (prerelease) (Debian 4.1.2-12)
CPU:
AMD AthlonXP 2200+
Kernel:
2.6.18-4-k7
io di solito quando ho problemi strani, per prima cosa faccio una trace del programma ... poi scrivo su hwu :D
strace -f -F -s 1024 -o <trace.out> <eseguibile>
dubito possa servire a molto perchè parli di librerie, ma può sempre aiutare
ilsensine
08-07-2007, 09:29
Gli header della libreria non sono in linea con la libreria stessa. Cose che capitano se usi la unstable.
Grazie a tutti per le risposte.
Riassumo:
1) [trallallero]
ho provato 'strace', ma non mi dice nulla di utile :-(
una cosa: mentre va, in 2 punti del programma mi scrive questo (non nel file trace.out ma nella shell):
umovestr: Input/output error
ptrace: umoven: Input/output error
è grave o è normale?
2) [cionci]
Non ho capito la domanda se la versione delle librerie è la stessa...
Se si riferisce alla varie distribuzioni, la risposta è non lo so, ma in generale no, difficile che 2 distro abbiano le stesse librerie di sistema, inoltre ho provato anche su Windows!
3) [ilsensine]
La chiamata che da errore è nelle Qt4 che però ho aggiornato varie volte (le ultime sono le nuove 4.3), aggiungo delle informazioni in merito...
Ho provato con varie versioni di Qt4: 4.2.2, 4.2.3, 4.3.0.
Il problema c'è da mesi e nonostante tutti gli aggiornamenti alla Debian e alle librerie Qt, non va mai via.
Inoltre la cosa strana è che quella funzione funziona benissimo se chiamata dopo certe operazioni, ma dà l'errore se chiamata dopo altre.
trallallero
08-07-2007, 11:10
1) [trallallero]
ho provato 'strace', ma non mi dice nulla di utile :-(
una cosa: mentre va, in 2 punti del programma mi scrive questo (non nel file trace.out ma nella shell):
umovestr: Input/output error
ptrace: umoven: Input/output error
è grave o è normale?
perchè non posti l'output di strace ? a te magari non dice niente ma a qualcun altro si
trallallero
08-07-2007, 11:19
hai delle librerie non compatibili, secondo me, ed è per qesto che ti compila e linka senza problemi ma crasha in runtime.
Non è che hai un sistema a 64 bit e alcune librerie non compatibili ? o viceversa (32 bit -> 64).
La sto sparando così, ma mi ricordo di aver letto un problema del genere ...
trallallero
08-07-2007, 11:26
ho googlato: umovestr
ed ho trovato questo: http://www.linuxquestions.org/questions/showthread.php?t=500463
parlano di 32/64 bit e debian
io più di così non so che fare :D
perchè non posti l'output di strace ? a te magari non dice niente ma a qualcun altro si
Certo! Solo non volevo tediarvi più di tanto...
Non è che hai un sistema a 64 bit e alcune librerie non compatibili ? o viceversa (32 bit -> 64).
E' difficile far girare un sistema a 64 bit su un AthlonXP :P
Comunque grazie per il tentativo...
Ehm... ho qualche problema ad allegare il file!
Altra serie di allegati...
Ultimi...
Perché tante restrizioni sugli allegati?
Il file è di 2.1 MB (txt), compresso con bzip2 è 173.3 KB, ma più di 24.4 KB non si possono allegare per file.
Così ho splittato il file in pezzi da 24 KB.
Solo che il risultato non aveva estensione e anche questo non viene accettato come allegato valido, così ho dovuto rinominarli tutti aggiungendo .txt alla fine.
trallallero
08-07-2007, 12:55
non funziona, dice archivio corrotto (ho concatenato tutti i files in ordine alfabetico e provato ad unzippare perchè immagino tu abbia prima zippato e poi splittato)
se vuoi mandami il file di trace via mail
I comandi da dare per ricomporre i files sono:
cat strace.out.bz2_* > strace.out.bz2
bunzip2 strace.out.bz2
Comunque nel caso non funzionasse nemmeno così, ho uploadato il file su questo sito (esperimento!):
http://files-upload.com/356785/strace.out.zip.html
trallallero
08-07-2007, 14:27
beh, si, non dice niente di più la trace.
l'unica cosa che si capisce è che il simbolo _ZN15QXmlInputSourceC1EP9QIODevice della libreria /home/alessandro/tesi/programma/assomac_jane_viewer/bin/libqtxml_plugin.so non è definito.
Ma che ci fa una libreria in una directory bin ? :mbe:
Perchè non vai nella directory /home/alessandro/tesi/programma/assomac_jane_viewer/bin e fai ldd libqtxml_plugin.so ?
mi piacciono 'ste cose da sistemare ma bisognerebbe essere sul posto, così da lontano non si hanno molte possibilità :boh:
Allora, cerco di spiegarti un po' come funziona...
Sto facendo un programma che legge dei files in formato XML.
Il problema è che in C++ non ci sono molti parser XML (anzi, sono veramente pochi) e non tutti implementano la validazione tramite XSD.
L'idea era di trovare un parser XML (SAX) che fosse multipiattaforma, con validazione XSD e senza bachi importanti.
L'unico che ho trovato è xerces-c.
Siccome non volevo essere legato ad un parser in particolare e siccome la validazione non è identica per tutti i parser (nessuno implementa tutte le funzioni ed ognuno sceglie un sottoinsieme a piacere), ho deciso di far funzionare il mio programma con un sistema a plugin. Il programma si aspetta un'interfaccia standard (che ho scritto io, seguendo l'interfaccia standard del Java, su cui XML è molto più standardizzato che in C++). Poi ho scritto dei plugin (DLL per Windows e SO per Linux) che implementano il parser usando librerie diverse.
Questo mi permette di cambiare parser senza modificare il programma e anche di usare parser diversi secondo la piattaforma su cui sta girando (così posso usare anche parser non multipiattaforma).
Al momento ho scritto 2 plugin: uno usa la libreria QtXml (tutto il programma è scritto con le librerie Qt4), l'altro usa xerces-c. Il primo non supporta la validazione, ma mi serve di test e come last-resort nel caso nessun altro plugin sia disponibile.
Veniamo alla funzione:
il codice incriminato è questo
XmlSaxPlugin::XmlParseResult XmlSaxPluginQtXml::parse(const QString &xmlUrl)
{
bool parseOk = false;
bool errorFound = false;
QXmlSimpleReader *reader = xmlReader();
if (reader == 0) {
genericError("Unable to parse: no XML reader available.");
errorFound = true;
} else {
try
{
QIODevice *inputFile = new QFile(xmlUrl);
QXmlInputSource *source = new QXmlInputSource(inputFile);
parseOk = reader->parse(source, false);
delete source;
delete inputFile;
}
catch (...) {
// Every other exception
genericError(QString("Unexpected Exception!"));
errorFound = true;
}
}
if(errorFound || !parseOk) {
// Parsing failed
return PARSE_ERROR;
} else {
// Successful parsing
return PARSE_VALID;
}
}
Questo plugin funziona benissimo normalmente, ma se lo chiamo dopo una particolare sequenza di operazioni, dà quell'errore.
La cosa veramente strana è questa! Come fa lo stesso pezzo di codice a funzionare e non funzionare secondo cosa ho chiamato prima???
L'ouput di ldd del mio plugin per Qt4 (comunque avevo già controllato) è:
linux-gate.so.1 => (0xffffe000)
libQtXml.so.4 => /usr/lib/libQtXml.so.4 (0xb7ece000)
libQtCore.so.4 => /usr/lib/libQtCore.so.4 (0xb7d50000)
libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7d39000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7c4e000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7c27000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7c1c000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7ad8000)
libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0xb7aad000)
libz.so.1 => /usr/lib/libz.so.1 (0xb7a98000)
libgthread-2.0.so.0 => /usr/lib/libgthread-2.0.so.0 (0xb7a94000)
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7a8b000)
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0xb79f8000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb79f3000)
/lib/ld-linux.so.2 (0x80000000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xb7989000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0xb7969000)
Tutte quelle righe vuote in fondo alle sezioni 'CODE' non le ho messe io :), è un problema del forum, suppongo.
Nel codice postato, l'uso di "try" e "catch" non serve a niente, era solo una prova, ma quelle funzioni non generano eccezioni (al limite le 'new' in caso di memoria finita).
Ti mostro anche il nome della funzione incriminata 'mangled e 'demangled':
U _ZN15QXmlInputSourceC1EP9QIODevice
U QXmlInputSource::QXmlInputSource(QIODevice*)
Ottenute rispettivamente con i comandi:
nm libqtxml_plugin.so
nm -C libqtxml_plugin.so
trallallero
08-07-2007, 17:19
beh caro IW2NHL (che nick facile da ricordare :D) non so più che dirti. Vedo che conosci già ldd, nm etc quindi su quello non posso esserti d'aiuto (pensavo fossi un utente windows magari un pò inesperto su ambienti unix-like ;))
Però non hai ancora detto che ci fa la libreria .so nella directory bin. Non è quello il problema perchè i linker, se non trova i riferimenti, blocca tutto, ma ... non si sa mai.
Ma ce l'hai il sorgente delle librerie ?
(domanda scema perchè lo sai che se hai il sorgente, compili con -g il tutto, debuggi e becchi l'errore vero ?)
Altra cosa: se googli "_N15QXmlInputSourceC1EP9QIODevice" esce un pò di roba tra cui: http://www.qtcentre.org/forum/f-qt-programming-2/t-strange-linking-error-at-run-time-7956-post42535.html
guarda caso, linker error ;)
PS: Le righe vuote io non le vedo :boh:
trallallero
08-07-2007, 17:28
uhm ... altra idea (ho risolto un problema dove lavoravo prima in questo modo).
vedo da quì: http://doc.trolltech.com/qtopia4.2/qxmlinputsource.html
che ci sono 2 costruttori:
QXmlInputSource::QXmlInputSource ( QIODevice * dev )
e
QXmlInputSource::QXmlInputSource ()
tu chiami il primo:
QXmlInputSource *source = new QXmlInputSource(inputFile);
hai provato a chiamare l'altro costruttore e settare dopo i dati ? (se si può fare ovviamente, ma se c'è il costruttore deduco si possa)
beh caro IW2NHL (che nick facile da ricordare :D) non so più che dirti. Vedo che conosci già ldd, nm etc quindi su quello non posso esserti d'aiuto (pensavo fossi un utente windows magari un pò inesperto su ambienti unix-like ;))
No, uso linux da tanti anni... però c'è sempre tanto da imparare!
Su ldd e nm ho imparato da poco (qualche mese) proprio per risolvere i miei problemi su questo programma.
Però non hai ancora detto che ci fa la libreria .so nella directory bin. Non è quello il problema perchè i linker, se non trova i riferimenti, blocca tutto, ma ... non si sa mai.
Scusa, pensavo fosse chiaro dalla mia presentazione del programma...
Quella librera è il plugin che ho scritto io! Visto che è relativa al programma, mi sembrava meglio lasciarla insieme a lui (almeno mentre la sto sviluppando).
Ma ce l'hai il sorgente delle librerie ?
(domanda scema perchè lo sai che se hai il sorgente, compili con -g il tutto, debuggi e becchi l'errore vero ?)
Ovvio che ho il sorgente, l'ho scritta io!
Inoltre il codice che ho postato prima era proprio parte della libreria.
Mi spiace, ma anche compilando con -g e analizzando con gdb non ho trovato nulla; tieni presente che il programma non va in crash, esce semplicemente e gdb non dà informazioni in merito, anche chiedendogli un 'backtrace' non esce nulla perché il programma è terminato e non crashato.
Comunque se sai come trovare l'errore dal sorgente, dimmi pure! Sicuramente c'è un modo per capire cosa sta succedendo, ma non lo conosco :cry:
Altra cosa: se googli "_N15QXmlInputSourceC1EP9QIODevice" esce un pò di roba tra cui: http://www.qtcentre.org/forum/f-qt-programming-2/t-strange-linking-error-at-run-time-7956-post42535.html
guarda caso, linker error ;)
Non pensavo che google fosse così rapido...
Comunque sono sempre io! Non hai notato lo stesso incomprensibile nick??? :D
Ho messo la domanda su più forum, ma l'unico in cui ho avuto qualche risposta è questo! HWU è sempre il migliore! Non per niente lo frequento da anni :O
PS: Le righe vuote io non le vedo :boh:
Questo è strano, che dipenda dal browser? Io uso firefox 2.0 da linux.
In ogni modo grazie per i tentativi e per il tempo dedicatomi!!!
Ti venisse in mente qualcosa di nuovo... fammi sapere!
uhm ... altra idea (ho risolto un problema dove lavoravo prima in questo modo).
[...]
hai provato a chiamare l'altro costruttore e settare dopo i dati ? (se si può fare ovviamente, ma se c'è il costruttore deduco si possa)
Grazie per l'idea: ho provato ma non cambia niente, si ferma sull'altro costruttore (quello senza parametri). :(
Ho notato che con una semplice modifica al codice, ho lo stesso errore su un'altra funzione, questa volta sulla chiamata ad una funzione mia e non Qt.
A questo punto sembra quasi un errore random, tipico di quando della memoria viene sovrascritta. Cosa ne pensi? Se è così, hai idea di come trovare cosa lo stia causando?
Magari è davvero un problema di librerie compilate con versioni diverse di compilatore in Debian testing.
trallallero
09-07-2007, 06:11
lo so che la libreria l'hai fatta tu, ma intendevo il sorgente del pacchetto libQtXml per riuscire ad entrare col debugger nella funzione QXmlInputSource :D
Senti, io al lavoro uso Linux e proprio Debian, se vuoi mi mandi tutto il sorgente che hai fatto e lo provo quì.
Ma, ovviamente, quì andrà tutto bene anche perchè sto in Cermania, funziona tutto quì :O
Al lavoro c'è un/a esporto/a (è trans :eek:) Debian (è proprio un/a gestore di pacchetti Debian, è stato/a a Edimburgo l'altra settimana per l'incontro con la comunità Debian ;)) magari riusciamo a capirci qualcosa.
E se per caso quì funge tutto, ti posso mandare le librerie che usiamo ;)
fammi sapere (trallallero trallalla @ gmail . com) tutto attaccato ovviamente
Grazie per la proposta.
Prima però voglio fare ancora qualche prova per capirci qualcosa di più, pensavo di provare qualche altra distro in questi giorni... magari anche con delle Live (tipo Knoppix). Se funziona dappertutto tranne che da me, mi metto il cuore in pace (e magari faccio un formattone!).
Inoltre mi è venuto in mente di provare a non fare l'unload del plugin dopo l'uso: sembra che questo risolva tutto!!!
Non ne capisco il motivo, ma comunque il plugin è pochi KB, anche se rimane in RAM non è un problema, poi viene tolto automaticamente alla chiusura del programma.
Faccio altre prove e poi ti faccio sapere.
Grazie ancora per il supporto!
Anche solo avere qualcuno con cui discuterne a volte aiuta, forse da solo mi sarei arreso prima senza trovare quella soluzione nuova.
trallallero
09-07-2007, 18:30
Grazie per la proposta.
Prima però voglio fare ancora qualche prova per capirci qualcosa di più, pensavo di provare qualche altra distro in questi giorni... magari anche con delle Live (tipo Knoppix). Se funziona dappertutto tranne che da me, mi metto il cuore in pace (e magari faccio un formattone!).
Inoltre mi è venuto in mente di provare a non fare l'unload del plugin dopo l'uso: sembra che questo risolva tutto!!!
Non ne capisco il motivo, ma comunque il plugin è pochi KB, anche se rimane in RAM non è un problema, poi viene tolto automaticamente alla chiusura del programma.
Faccio altre prove e poi ti faccio sapere.
Grazie ancora per il supporto!
Anche solo avere qualcuno con cui discuterne a volte aiuta, forse da solo mi sarei arreso prima senza trovare quella soluzione nuova.
di niente, figurati. Si chiama debugging del confessionale (o qualcosa del genere :D) ... parli con altri del problema e ... trovi la soluzione da solo.
ciao
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.