This is what I gathered from disassembling so far: and comparing the maverick and natty QtGui libs, looking at the QGestureManager constructor where the crash occurs. It includes a macro which in turn includes a few nested inline functions. This is the macro included in the constructor, copied from http://qt.gitorious.org/qt/qt/blobs/4.7/src/corelib/kernel/qmetatype.h 265 #define Q_DECLARE_METATYPE(TYPE) \ 266 QT_BEGIN_NAMESPACE \ 267 template <> \ 268 struct QMetaTypeId< TYPE > \ 269 { \ 270 enum { Defined = 1 }; \ 271 static int qt_metatype_id() \ 272 { \ 273 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \ 274 if (!metatype_id) \ 275 metatype_id = qRegisterMetaType< TYPE >(#TYPE, \ 276 reinterpret_cast< TYPE *>(quintptr(-1))); \ 277 return metatype_id; \ 278 } \ 279 }; \ 280 QT_END_NAMESPACE QBasicAtomicInt has a volatile int _q_value field, which is it's only field, initialized at 0 in line 273. Line 274 invokes the ! operator in qbasicatomic.h, which is simply { return _q_value == 0;} Line 277 invokes the int() operator of qbasicatomic.h which is simply { return _q_value;} Both of the above operators are expanded inline Here's the disassembly of lines 274-277 in libQtGUI.so.4.7.0 (the working one, built with gcc 4.4) Check for _q_value 0 using ! operator 169178: 4e3e ldr r6, [pc, #248] ; (169274 <_ZN18QGestureRecognizerD0Ev+0x348>) 16917a: 59ab ldr r3, [r5, r6] get _q_value 16917c: b943 cbnz r3, 169190 <_ZN18QGestureRecognizerD0Ev+0x264> if zero do the work between the brackets 16917e: 4b3e ldr r3, [pc, #248] ; (169278 <_ZN18QGestureRecognizerD0Ev+0x34c>) 169180: 493e ldr r1, [pc, #248] ; (16927c <_ZN18QGestureRecognizerD0Ev+0x350>) 169182: 4a3f ldr r2, [pc, #252] ; (169280 <_ZN18QGestureRecognizerD0Ev+0x354>) 169184: 18e8 adds r0, r5, r3 169186: 1869 adds r1, r5, r1 169188: 18aa adds r2, r5, r2 16918a: f7ae ef2a blx 117fe0 <_init+0x2cdc> 16918e: 51a8 str r0, [r5, r6] set _q_value return metatype_id - _q_value via the int() operator. 169190: 2004 movs r0, #4 169192: 59ab ldr r3, [r5, r6] get _q_value 169194: f7ae e82c blx 1171f0 <_init+0x1eec> Notice that _q_value is accessed the same way, at offset r5+r6 in the two ldr and the str instruction. r5 and r6 are set up previously in the function. ============================================================================================== Whereas in 4.7.1 (the one built with 4.5 in natty) Load _q_value via ! operator 160e1e: 4b3f ldr r3, [pc, #252] 160e20: 447b add r3, pc 160e22: 681b ldr r3, [r3, #0] 160e24: 2b00 cmp r3, #0 If 0 jump somewhere else (unlike above here the work within braces was moved further out in the generated code) 160e26: d035 beq.n 160e94 <_ZN18QGestureRecognizer20unregisterRecognizerEN2Qt11GestureTypeE+0x4cc> otherwise return _q_value via int() operator 160e28: 2004 movs r0, #4 160e2a: 447b add r3, pc 160e2c: 681b ldr r3, [r3, #0] ================= location of SEGFAULT ============================= 160e2e: f7b5 eace blx 1163cc <_init+0x1dcc> Notice that the two accesses to _q_value are not using the same offsets - or it is not obvious. They are using pc relative loads and then another load based on that value. In the beq not taken case, before it r3 references _q_value and is checked against 0, then after it is is used as if it were an offset and pc is added to it. Here's the work between brackets, note the preparation for the last store uses the same type of load (at least it sets up r3 from a known offset before adding pc to it) 160e94: 4822 ldr r0, [pc, #136] 160e96: f04f 31ff mov.w r1, #4294967295 160e9a: 4478 add r0, pc 160e9c: f005 f8ba bl 166014 160ea0: 4b20 ldr r3, [pc, #128] 160ea2: 447b add r3, pc 160ea4: 6018 str r0, [r3, #0]