ARMv7 latest master segfaults in QPrinter deconstructor in musescore.cpp:6058

• Jan 12, 2018 - 06:14

I don't know when this problem occured or if this problem is something with my labtop, as I haven't compiled musescore on my arm arch linux labtop in a few months. I'm on latest master ec85457 building in QtCreator 4.5 with Qt 5.10. Anyway, at the end of this block, the QPrinter object p gets deconstruction, and for somereason way inside that deconstructor there is a segfault. Unfortunately it is all asm down in these levels, so I don't have a good idea what is happening. I'm going to look into this some more, but just incase someone has an idea. Here is the stack trace:

1 QRegion::~QRegion() 0xb1dbcd14
2 QPaintEnginePrivate::~QPaintEnginePrivate paintengine_p.h 66 0xfd4440
3 QPdfEnginePrivate::~QPdfEnginePrivate() 0xb1da466c
4 QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate() 0xb6630b20
5 QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate() 0xb6630b84
6 QPaintEngine::~QPaintEngine() 0xb1d5a3b4
7 QPdfPrintEngine::~QPdfPrintEngine() 0xb66308ac
8 QPdfPrintEngine::~QPdfPrintEngine() 0xb66308d0
9 QPrinter::~QPrinter() 0xb6633b0c
10 main musescore.cpp 6058 0xcc75dc


Comments

Seems if I #define QT_NO_PRINTER in globals.h, then this particular crash is avoided, but a new one later is in genIcons() when invoke icon->pixmap(12)...here is stacktrace:

1 QRegion::~QRegion() 0xb1dbcd14
2 QPaintEnginePrivate::~QPaintEnginePrivate paintengine_p.h 66 0xfd2438
3 QPaintEngineExPrivate::~QPaintEngineExPrivate() 0xb1d60a68
4 ?? 0xb1d779c8

not very helpful. I don't know what to do at this point...giving up. I guess I could try an earlier version of Qt, since it seems the current Qt is almost likely at fault considering earlier version of Qt would work.

In reply to by [DELETED] 5

Thanks lasconic for telling me the version...After downgrading my qt install from 5.10.0-1 to 5.9.3-1, then musescore nightly started fine.

The best way to get the nightly arm running is to have it use the same OS for Dockerfile and then that way can use the same AppImage Recipe script. Then don't have to maintain different scripts for each OS. (I had used Debian for building the arm image, while x86 currently uses ubuntu.)

So it seems this bug also affect 2.0.3 on arm when have arch's Qt 5.10.0-4 installed, as I get a segfault when starting. From exporting QT_DEBUG_PLUGINS=1 before running, I see that the crash occurs when checking printer support (full log attached):

Got keys from plugin meta data ("cupsprintersupport")
QFactoryLoader::QFactoryLoader() checking directory path "/usr/bin/printsupport" ...
loaded library "/usr/lib/qt/plugins/printsupport/libcupsprintersupport.so"
Segmentation fault (core dumped)

I compiled Qt 5.10.1 with debugging symbols on my arch linux machine and compiled MuseScore 2.2 with it and now have a more informative stack trace:

1 std::__atomic_base::load atomic_base.h 396 0xb295a64c
2 QAtomicOps::load qatomic_cxx11.h 227 0xb295a64c
3 QBasicAtomicInteger::load qbasicatomic.h 102 0xb295a64c
4 QtPrivate::RefCount::deref qrefcount.h 66 0xb295a64c
5 QRegion::~QRegion qregion.cpp 3997 0xb295a64c
6 QPaintEnginePrivate::~QPaintEnginePrivate paintengine_p.h 66 0xec3d7c
7 QPdfEnginePrivate::~QPdfEnginePrivate qpdf.cpp 1532 0xb29460dc
8 QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate qprintengine_pdf.cpp 406 0xb6160170
9 QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate qprintengine_pdf.cpp 408 0xb61601a8
10 QScopedPointerDeleter::cleanup qscopedpointer.h 60 0xb28e6fc0
11 QScopedPointer>::~QScopedPointer qscopedpointer.h 107 0xb28e6fc0
12 QPaintEngine::~QPaintEngine qpaintengine.cpp 722 0xb28e6fc0
13 QPdfEngine::~QPdfEngine qpdf_p.h 179 0xb615fe54
14 QPdfPrintEngine::~QPdfPrintEngine qprintengine_pdf.cpp 75 0xb615fe54
15 QPdfPrintEngine::~QPdfPrintEngine qprintengine_pdf.cpp 77 0xb615fe78
16 QPrinter::~QPrinter qprinter.cpp 627 0xb6166cf0
17 main

(I think this stack trace is larger because it knows about inlined functions).

the crashing function is at the end of this inlined std library atomic load:

  _GLIBCXX_ALWAYS_INLINE __int_type
  load(memory_order __m = memory_order_seq_cst) const noexcept
  {
memory_order __b = __m & __memory_order_mask;
__glibcxx_assert(__b != memory_order_release);
__glibcxx_assert(__b != memory_order_acq_rel);

return __atomic_load_n(&_M_i, __m);
  }

When I look at the disassembler, it is trying to load from memory address -1. That memory address containing -1 was loaded from address [02614718] which contains ffff (-1). Of course that doesn't tell me much other than the problem is deeper, mayber at the std library level or at next higher level of QAtomicOps.

In reply to by ericfontainejazz

looking some more, seems that the struct __atomic_base object's this pointer is 0xffffffff.

At the next level up, QAtomicOps::load(const std::atomic &_q_value) was called with _q_value = 0xffffffff. So that leads me to think it is not the std library's fault.

Also at the next level up, QBasicAtomicInteger::load(), the this pointer = 0xffffffff.

Also at the next level up, QtPrivate::QtRef::deref() the this pointer = 0xffffffff.

At the next level up:

QRegion::~QRegion()
{
if (!d->ref.deref())
cleanUp(d);
}

The struct QRegionData *d is also 0xffffffff.

At the next level up, class QPaintEnginePrivate contains a QRegion obejct "systemClip" and I guess that is the problematic thing being deconstructed. Because it has a non-null QPaintEnginePrivate object:

    this    @0x2614458  QPaintEnginePrivate
        [vptr]  _vptr.QPaintEnginePrivate    
        currentClipWidget   0x0 QWidget*
        hasSystemTransform  0   uint{unsigned int} : 1
        hasSystemViewport   0   uint{unsigned int} : 1
        pdev    0x0 QPaintDevice*
        q_ptr   @0x2614128  QPaintEngine
        systemClip  <0 items> QRegion
        systemRect  1297335753x0-1297335752+0   QRect
        systemTransform @0x2614480  QTransform
        systemViewport  

It seems most of these things are uninitialized, in particular 'systemClip' has "0 items". I don't know if that has anything to do wit it, but now I might try seeing if initializing systemClip to contain something might allow the deconstructor to work...

In reply to by ericfontainejazz

(these are all just notes for myself)

So I found where that QRegion gets constructed in line 3961 of qregion.cpp:

QRegion::QRegion()
: d(const_cast(&shared_empty))
{
}

where that shared_empty is:

    shared_empty    @0xb2ac3a38 QRegion::QRegionData
        qt_rgn  @0xb2ad3880 QRegionPrivate
            extents 0x0+0+0 QRect
            innerArea   -1  int
            innerRect   0x0+0+0 QRect
            numRects    0   int
            rects   <0 items> QVector
        ref @0xb2ac3a38 QtPrivate::RefCount
            atomic  -1  QBasicAtomicInt

I wonder why ref (the reference counter?) is -1...I would think reference counter would start at 0...but of course I don't know much about the internal implementation.

Anyway the QRegion gets initialized with:

        numRects    0   int
        innerArea   -1  int
        extents 0x0+0+0 QRect
            x1  0   int
            y1  0   int
            x2  -1  int
            y2  -1  int
        innerRect   0x0+0+0 QRect
            x1  0   int
            y1  0   int
            x2  -1  int
            y2  -1  int
        rects   <0 items> QVector

which seems normal.

I've discovered the fix. The problem was very hard to spot. Turns out musescore had been using an out-of-date private header file which was copy-and-pasted over 6 years ago, and which has since divereged and no-longer represents how Qt 5.10 stores the class. I've made an actual issue named according to this fact along with the fix: #269845: may crash before splash screen on 2.1, 2.2, or master with Qt 5.10 due to diverged copy-and-pasted QPaintEnginePrivate header file

Do you still have an unanswered question? Please log in first to post your question.