I'm trying to use Qt 4.7.4 on an ARM system, in order to display a graphic application on a touchscreen.
My ARM card embeds a Linux system; we use the Linux framebuffer to send information to the screen, and tslib+usbtouchscreen drivers to get the touch information.
I'm able to cross-compile Qt and put the library on my system. But when I launch my test program, I get a segfault every time at the same moment (without logical reason).
To begin with, here is my test program (you can see it's very basic, no reason to segfault) :
#include <QMessageBox>
#include <QApplication>
int main( int argc, char *argv[] )
{
QApplication app( argc, argv );
QMessageBox msgBox;
msgBox.setText( "Hello world !" );
msgBox.show();
return app.exec();
}
The segfault appends during the show()
call, in fact (thanks to some debugging), I realized it appends during the loading of font cache. Moreover, adding a printf()
just after the call to localData()
makes the segfault disappear... for a moment! However, when I close the application, I get the segfault anyway.
In Qt/gui/text/qfont.cpp
line 2615, adding a printf()
after theFontCache()->loadData()
temporarily resolves the problem:
QFontCache *QFontCache::instance()
{
QFontCache *&fontCache = theFontCache()->localData();
if (!fontCache) {
fontCache = new QFontCache;
}
return fontCache;
}
Here is my ./configure
command line :
./configure -release -shared -fast -no-largefile -exceptions -no-accessibility -no-stl -no-qt3support -no-xmlpatterns -no-phonon -no-phonon-backend -no-svg -no-webkit -no-declarative -no-declarative-debug -no-glib -no-cups -no-scripttools -no-script -no-audio-backend -no-multimedia -no-nis -embedded arm -xplatform qws/linux-arm-str-g++ -little-endian -no-gfx-multiscreen -prefix /usr -qconfig mbxconfig -nomake examples -nomake demos -depths 16 -qt-mouse-tslib -confirm-license -opensource
I tried to configure with -no-freetype
; nothing changed. I also tried to force the font, but no success neither. I also tried echo 3 > /proc/cpu/alignment
but I didn't find any alignment problem that way. One solution that I would try: compile without the compiler optimization - but I apparently didn't change the right options, since it still compiles with -O2
. My GCC version is 4.2.3.
Last, my strace before the segfault :
open("/dev/psaux", O_RDWR|O_NONBLOCK) = -1 ENOENT (No such file or directory)
open("/dev/input/mice", O_RDWR|O_NONBLOCK) = -1 ENOENT (No such file or directory)
open("/dev/tty0", O_RDWR) = 8
fcntl(8, F_SETFD, FD_CLOEXEC) = 0
ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(8, KDGKBMODE, 0x1a21c) = 0
ioctl(8, KDSKBMODE, 0x2) = 0
ioctl(8, SNDCTL_TMR_START or TCSETS, {B0 -opost -isig -icanon -echo ...}) = 0
ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 -opost -isig -icanon -echo ...}) = 0
rt_sigaction(SIGUSR1, {0x40bb3d68, [], 0x4000000 /* SA_??? */}, NULL, 8) = 0
rt_sigaction(SIGUSR2, {0x40bb3d68, [], 0x4000000 /* SA_??? */}, NULL, 8) = 0
ioctl(8, VIDIOC_RESERVED or VT_GETMODE, 0xbedbb598) = 0
ioctl(8, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbedbb598) = 0
ioctl(8, VT_GETSTATE, 0xbedbb588) = 0
gettimeofday({1321521340, 447374}, NULL) = 0
brk(0x1d000) = 0x1d000
open("/proc/self/auxv", O_RDONLY) = 9
fcntl(9, F_SETFD, FD_CLOEXEC) = 0
read(9, "\20\0\0\0\3\0\0\0\6\0\0\0\0\20\0\0\21\0\0\0d\0\0\0\3\0\0\0004\200\0\0\4"..., 256) = 128
read(9, ""..., 256) = 0
close(9) = 0
write(4, "\0"..., 1) = 1
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
rt_sigaction(SIGSEGV, {SIG_DFL, [SEGV], SA_RESTART|0x4000000}, {0x40142d48, [SEGV], SA_RESTART|0x4000000}, 8) = 0
ioctl(8, KDSKBMODE, 0x3) = 0
ioctl(8, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
close(8) = 0
ioctl(7, KDSETMODE, 0) = 0
write(7, "\33[9;15]\33[?33h\33[?25h\33[?0c\0"..., 25) = 25
close(7) = 0
kill(29810, SIGSEGV) = 0
sigreturn() = ? (mask now [])
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
On the ARM system, I don't have enough space to compile with debug so that's why it's directly in release.
According to bug report linked in some pages https://bugreports.qt.io/browse/QTBUG-13441
SEGV is in ../3rdparty/harfbuzz/src/harfbuzz-* (two backtraces are posted and both ended in ../3rdparty/harfbuzz/src/harfbuzz-gsub.c
)
So, you should try to rebuild only this 3rd party library "harfbuzz" with -g -O2
and -g -O0
. As it is 3rdparty, it has its own build system, and I think it can be changed easily.
When you will prove that your bug is in this library too and that it depends on -O2/-O0 flag, you can:
x/i $pc
from GDB and info reg
to see where is the SEGV data is and what is the action.Also, the strace is almost not interesting and the gdb's backtrace is.
Update from Jérémy Dutheil: "Simply by compiling with -Os option : no more segfault, and very small size for libs! " -- So if O2 fails, O1 and/or Os should be tried too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With