PDA

View Full Version : trying to port an application to qt4.8 : qstring ambigous error



cr3005
19th November 2012, 11:33
hello

I have this little cool application, reveal, which is a exif metadata viewer. It is from 2006, coded with qt4. Apart from some minor adjustments, it compiles until



g++ -c -pipe -O2 -O2 -I/usr/include -D_REENTRANT -Wall -W -DBIN_DIR=\""/usr/bin\"" -DRESOURCE_DIR=\""/usr/share/Reveal\"" -DTARGET=\""Reveal\"" -DNEEDED_TRANSLATIONS=\""Reveal commonDialogs generalTools qt\"" -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtXml -I/usr/include/qt4 -Itmp -o tmp/dynamicSlider.o ../src/_commonWidgets/dynamicSlider.cpp
../src/_commonWidgets/dynamicSlider.cpp: In member function 'void DynamicSlider::setPrefix(QString)':
../src/_commonWidgets/dynamicSlider.cpp:54:27: error: call of overloaded 'QString(NULL)' is ambiguous
/usr/include/qt4/QtCore/qstring.h:428:43: note: candidates are: QString::QString(const QByteArray&)
/usr/include/qt4/QtCore/qstring.h:426:43: note: QString::QString(const char*)
/usr/include/qt4/QtCore/qstring.h:727:8: note: QString::QString(const QString&)
/usr/include/qt4/QtCore/qstring.h:106:5: note: QString::QString(QChar)
/usr/include/qt4/QtCore/qstring.h:105:14: note: QString::QString(const QChar*)
../src/_commonWidgets/dynamicSlider.cpp: In member function 'void DynamicSlider::setSuffix(QString)':
../src/_commonWidgets/dynamicSlider.cpp:68:27: error: call of overloaded 'QString(NULL)' is ambiguous
/usr/include/qt4/QtCore/qstring.h:428:43: note: candidates are: QString::QString(const QByteArray&)
/usr/include/qt4/QtCore/qstring.h:426:43: note: QString::QString(const char*)
/usr/include/qt4/QtCore/qstring.h:727:8: note: QString::QString(const QString&)
/usr/include/qt4/QtCore/qstring.h:106:5: note: QString::QString(QChar)
/usr/include/qt4/QtCore/qstring.h:105:14: note: QString::QString(const QChar*)
make: *** [tmp/dynamicSlider.o] Error 1



where the file looks like this:



void DynamicSlider::setPrefix( QString val )
{
prefix1 = val;
prefix2 = QString( NULL );
updateTooltipLabel();
}
//==========================================
void DynamicSlider::setPrefixes( QString v1, QString v2 )
{
prefix1 = v1;
prefix2 = v2;
updateTooltipLabel();
}
//==========================================
void DynamicSlider::setSuffix( QString val )
{
suffix1 = val;
suffix2 = QString( NULL );
updateTooltipLabel();
}



and .h




///set two prefix values, one for when the value is positive and one for when the value is negative.
void setPrefixes( QString prefix1, QString prefix2 );

///set the suffix that is displayed after the current slider value
void setSuffix( QString val );

///set two suffix values, one for when the value is positive and one for when the value is negative.
void setSuffixes( QString suffix1, QString suffix2 );



Now, with qt4.7, when I delete the NULL, it compiles through and runs.

With qt 4.8, I get a segmentation fault, gdb tells it faults in Qstring::fromLocal8Bit(char const*, int) ()

I am not familiar with qt, could somebody help me out?

thx in advance

amleto
19th November 2012, 15:17
just replace

QString(NULL)

with

""


e.g.


suffix2 = "";

anda_skoa
19th November 2012, 15:44
Just replace QString( NULL ) with QString() or call the string variable's clear() method.

Cheers,
_

cr3005
19th November 2012, 15:53
just replace

QString(NULL)

with

""


e.g.


suffix2 = "";

hmm, nope, just keeps segfaulting...

Added after 6 minutes:


Just replace QString( NULL ) with QString()

Cheers,
_

As I stated in my beginning post, I DID replace QString( NULL ) with QString() and it compiled through, but it segfaults with 4.8...
0x00007ffff5eb5b40 in Qstring::fromLocal8Bit(char const*, int) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4


or call the string variable's clear() method.
will try that, if I find out how...

amleto
19th November 2012, 15:55
sounds like maybe you have got too many Qt installs are are mixing up library binaries?

but since you have a runtime error, the issue is not likely to be syntax problem... More probable is data/value problem. Since you didnt show how that segfault is traced from your code, you are not making things easy to diagnose.

cr3005
19th November 2012, 16:18
sounds like you have got too many Qt installs are are mixing up library binaries?

nope, qt4.7 is on a ubuntu 10.10, 4.8 in a vm with 12.04... where I am trying to get it run, and there is definitely no second qt installed..

Added after 8 minutes:




but since you have a runtime error, the issue is not likely to be syntax problem... More probable is data/value problem. Since you didnt show how that segfault is traced from your code, you are not making things easy to diagnose.
As I said, I am not familiar with qt, but I guess I have to edit the Reveal.pro file, which has these contents: http://paste.ubuntu.com/1370379

Added after 12 minutes:

ok, I installed qt debugging symbols, and without recompliation, it now tells :



(gdb) run
Starting program: /home/hero/Downloads/clay_2006_10_17/projects/Reveal
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe8bc5700 (LWP 8387)]
[New Thread 0x7fffe3fff700 (LWP 8388)]

Program received signal SIGSEGV, Segmentation fault.
QString::fromLocal8Bit (str=0x21 <Address 0x21 out of bounds>, size=-1) at tools/qstring.cpp:3960
3960 tools/qstring.cpp: No such file or directory.


and I cannot find a qstring.cpp file on my 12.04 system


hmm, recompiling with CONFIG+= qt debug added to Reveal.pro created the debugging symbols for Reveal, but did not change the gdb output...

amleto
19th November 2012, 16:36
"I installed qt debuggung symbols"
I don't know what this means.

Did you recompile Qt on your 12.04 sys?

Can't you run the debugger and obtain the stack trace?


*What is most useful information is the last line of your code that is executed before the seg fault, and the value of all variables at that stack level*
That's basic information for diagnosing seg faults like this.

cr3005
19th November 2012, 16:47
"I installed qt debuggung symbols"
I don't know what this means.

Did you recompile Qt on your 12.04 sys?

Can't you run the debugger and obtain the stack trace?

I thought that download and install the libqt4-dbg package (319mb size) would actually install the debugging symbols for all qt libraries?

sorry, I am a bit rusty with all that, here is the bt:


(gdb) run
Starting program: /home/hero/Downloads/clay_2006_10_17/projects/Reveal
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe8bc5700 (LWP 8637)]
[New Thread 0x7fffe3fff700 (LWP 8638)]

Program received signal SIGSEGV, Segmentation fault.
QString::fromLocal8Bit (str=0x21 <Address 0x21 out of bounds>, size=-1) at tools/qstring.cpp:3960
3960 tools/qstring.cpp: No such file or directory.
(gdb) bt
#0 QString::fromLocal8Bit (str=0x21 <Address 0x21 out of bounds>, size=-1) at tools/qstring.cpp:3960
#1 0x00007ffff5f6ec8b in QCoreApplication::arguments () at kernel/qcoreapplication.cpp:2235
#2 0x00007ffff685cda0 in sm_performSaveYourself (smd=0x6ffdb0) at kernel/qapplication_x11.cpp:6078
#3 0x00007ffff685d989 in sm_saveYourselfCallback (smcConn=<optimized out>, clientData=<optimized out>, saveType=<optimized out>,
shutdown=<optimized out>, interactStyle=<optimized out>) at kernel/qapplication_x11.cpp:6061
#4 0x00007ffff3faadff in _SmcProcessMessage () from /usr/lib/x86_64-linux-gnu/libSM.so.6
#5 0x00007ffff3d9cfd6 in IceProcessMessages () from /usr/lib/x86_64-linux-gnu/libICE.so.6
#6 0x00007ffff5f81281 in QMetaObject::activate (sender=0x705c90, m=<optimized out>, local_signal_index=<optimized out>, argv=0x7fffffffd720)
at kernel/qobject.cpp:3547
#7 0x00007ffff5fce2fe in QSocketNotifier::activated (this=<optimized out>, _t1=15) at .moc/release-shared/moc_qsocketnotifier.cpp:103
#8 0x00007ffff5f8a60b in QSocketNotifier::event (this=0x705c90, e=0x7fffffffdd40) at kernel/qsocketnotifier.cpp:317
#9 0x00007ffff67db894 in notify_helper (e=0x7fffffffdd40, receiver=0x705c90, this=0x6a18d0) at kernel/qapplication.cpp:4559
#10 QApplicationPrivate::notify_helper (this=0x6a18d0, receiver=0x705c90, e=0x7fffffffdd40) at kernel/qapplication.cpp:4531
#11 0x00007ffff67e0713 in QApplication::notify (this=0x7fffffffdfc0, receiver=0x705c90, e=0x7fffffffdd40) at kernel/qapplication.cpp:4420
#12 0x00007ffff5f6ce9c in QCoreApplication::notifyInternal (this=0x7fffffffdfc0, receiver=0x705c90, event=0x7fffffffdd40)
at kernel/qcoreapplication.cpp:876
#13 0x00007ffff5f9ba97 in sendEvent (event=0x7fffffffdd40, receiver=<optimized out>)
at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:231
#14 socketNotifierSourceDispatch (source=0x6a4b90) at kernel/qeventdispatcher_glib.cpp:110
#15 0x00007ffff4908d53 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#16 0x00007ffff49090a0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 0x00007ffff4909164 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#18 0x00007ffff5f9c3bf in QEventDispatcherGlib::processEvents (this=0x6a3640, flags=...) at kernel/qeventdispatcher_glib.cpp:424
#19 0x00007ffff6883d5e in QGuiEventDispatcherGlib::processEvents (this=<optimized out>, flags=...) at kernel/qguieventdispatcher_glib.cpp:204
#20 0x00007ffff5f6bc82 in QEventLoop::processEvents (this=<optimized out>, flags=...) at kernel/qeventloop.cpp:149
#21 0x00007ffff5f6bed7 in QEventLoop::exec (this=0x7fffffffdf50, flags=...) at kernel/qeventloop.cpp:204
#22 0x00007ffff5f70f67 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1148
#23 0x00000000004131de in main ()



As I have fiddled around on command-line only until now, I will have to install qt creator to debug this properly I guess. I just thought it wasn't necessary, as the program works fine with qt4.7...

The problem is that I have to include an old version of exiv2 to get the program to work, and I know how to set paths and environment variables right to do so on command line, but all these things do not work when using qt-creator, so I am stuck, as I would have to learn how to edit pri files to add library paths etc..

amleto
19th November 2012, 17:48
I don't know how 'installing' qt works on nix. I would be surprised if you didn't need to compile it since it is not known what compiler you will be using...

I don't see any of your code in that call stack. That points even more to bad build/linking.

cr3005
19th November 2012, 18:17
oh well trust me, that's alright and works fine.

But I actually have no clue why the back-trace is as is, without mentioning the code of the program.. as you say.


That points even more to bad build/linking.
I am shure that, compiling-wise, from qt standpoint, everything is as it should be. the right libraries are installed. the right things happen at compile-time, it compiles through. All things I have adapted compile-wise are because of an older exiv2 library needed by the program.

amleto
19th November 2012, 19:19
All things I have adapted compile-wise are because of an older exiv2 library needed by the program.
The tail wagging the dog :)

likely suspects
1) mis-matched compiler
2) mis-matched run times
3) mis-matched debug/release binaries
4) mis-matched compiler options
5) something messing with that char* memory location
6) ?


Have you built the examples in 12.04? How well do the examples work?


ps, your call stack looks like a release build...

cr3005
19th November 2012, 19:35
you actually underestimate the linux packaging system; it reliefs you from the burden of thinking about such details, and compiling a separate qt makes no sense, as I want that little app (under 2 mb with supported libraries) have to stay little; If I do not get it to run, I can just pack qt4.7 libs into a folder and it runs. but that would be a waste of space. And for my purpose, space is the thing I really do not want to waste.


the release build is 720kb, the debug build 4.5mb..
here you can see that the debugging symbols are loaded: http://paste.ubuntu.com/1370858

amleto
19th November 2012, 23:09
Have you built the examples in 12.04? How well do the examples work?


^^^^^^^^^^^^

cr3005
20th November 2012, 07:10
^^^^^^^^^^^^

ok will try.

Added after 18 minutes:

Actually found the solution. What a good sleep can make a difference:)



//==========================================
void DynamicSlider::setPrefix( QString val )
{
prefix1 = val;
prefix2 = QString();
prefix2.clear();
updateTooltipLabel();
}
//==========================================
void DynamicSlider::setPrefixes( QString v1, QString v2 )
{
prefix1 = v1;
prefix2 = v2;
updateTooltipLabel();
}
//==========================================
void DynamicSlider::setSuffix( QString val )
{
suffix1 = val;
suffix2 = QString();
suffix2.clear();
updateTooltipLabel();
}



thanks for all anyways to kindly give me a bit of your time.

amleto
20th November 2012, 11:14
That's not the solution. That's not even *a* solution. That's a work-around.

and you never tried my suggestion of ... = ""; instead of ... = QString(); I would be interested to know if that works or not.

anda_skoa
20th November 2012, 17:34
and you never tried my suggestion of ... = ""; instead of ... = QString(); I would be interested to know if that works or not.

That would be almost the same. Assigning "" creates and empty non-null string (isEmpty() && !isNull()), assigning QString() creates and empty, null string (isEmpty() && isNull()).

The clear() calls in the code snippet are basically no-ops, because the string is a null string, so clearing it doesn't change anything.

One other difference between assigning "" and assigning QString() is that the latter will always compile, while the former needs QString( const char * ) to be available which is not the case if the code is built with Q_NO_CAST_FROM_ASCII

Cheers,
_

amleto
20th November 2012, 19:29
That would be almost the same. Assigning "" creates and empty non-null string (isEmpty() && !isNull()), assigning QString() creates and empty, null string (isEmpty() && isNull()).
Yes, I know. Almost being the key word. Maybe there is some eliding in one that doesn't happen in the other.

The clear() calls in the code snippet are basically no-ops, because the string is a null string, so clearing it doesn't change anything.
If this is the only difference and 'fixes' the issue, then it cannot be a no-op



thanks for, well, stating the obvious I guess.