Results 1 to 4 of 4

Thread: Is this a bug?

  1. #1
    Join Date
    Apr 2010
    Posts
    8
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X

    Default Is this a bug?

    Hi everbody,

    I have found a strange behavior while using QT5 which - for me -seems to be a bug. I would like to discuss this here.
    I have posted the behavior description in the following QWT related thread in this forum:

    http://www.qtcentre.org/threads/5710...8race-cond-%29

    However, I found out that it is an issue related to QT5 rather than QWT: Here is the short version of the description (I use QT 5.2,
    Visual Studio 2012, Windows 7):

    The problem is related to loading a class declared as a metatype by using the Q_DECLARE_METATYPE macro from a dll.
    When first loading the dll, the Q_DECLARE_METATYPE macro initiates a call to function QMetaType::registerNormalizedType
    in file qmetatype.cpp where the type as well as the symbols creator, deleter, constructor and destructor
    are registered.
    When now unloading and reloading the dll, the symbols for the callbacks creator, deleter, constructor and
    destructor should be updated in function QMetaType::registerNormalizedType in file qmetatype.cpp
    since the addresses of creator, deleter, constructor and destructor may have changed. This does
    not happen since it is detected that the type has been registered before.
    If the symbols are not updated, the old symbols may be used as a target to a callback which point to invalid
    memory segments which leads to a crash of the application.

    Note: In an application with multiple dlls loaded at runtime, the symbols form the first time loading the dll may be identical
    to the symbols for the 4 callbacks if all dlls are loaded in identical order. the described crash happen only if
    the dlls are loaded in a different order compared toi the first time. Therefore, this does not happen all the time.

    And here is my fix to function QMetaType::registerNormalizedType
    in file qmetatype.cpp which prevents my application from crashing
    (modification NEW CODE vs OLD CODE):

    Qt Code:
    1. int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
    2. Creator creator,
    3. Destructor destructor,
    4. Constructor constructor,
    5. int size, TypeFlags flags, const QMetaObject *metaObject)
    6. {
    7. QVector<QCustomTypeInfo> *ct = customTypes();
    8. if (!ct || normalizedTypeName.isEmpty() || !deleter || !creator || !destructor || !constructor)
    9. return -1;
    10.  
    11. int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
    12. normalizedTypeName.size());
    13.  
    14. int previousSize = 0;
    15. int previousFlags = 0;
    16. if (idx == UnknownType) {
    17. QWriteLocker locker(customTypesLock());
    18. idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
    19. normalizedTypeName.size());
    20. if (idx == UnknownType) {
    21. QCustomTypeInfo inf;
    22. inf.typeName = normalizedTypeName;
    23. inf.creator = creator;
    24. inf.deleter = deleter;
    25. #ifndef QT_NO_DATASTREAM
    26. inf.loadOp = 0;
    27. inf.saveOp = 0;
    28. #endif
    29. inf.alias = -1;
    30. inf.constructor = constructor;
    31. inf.destructor = destructor;
    32. inf.size = size;
    33. inf.flags = flags;
    34. inf.metaObject = metaObject;
    35. idx = ct->size() + User;
    36. ct->append(inf);
    37. return idx;
    38. }
    39.  
    40. if (idx >= User) {
    41.  
    42. /* NEW CODE */
    43. QCustomTypeInfo ttt = ct->at(idx - User);
    44. previousSize = ttt.size;
    45. previousFlags = ttt.flags;
    46. ttt.creator = creator;
    47. ttt.deleter = deleter;
    48. ttt.constructor = constructor;
    49. ttt.destructor = destructor;
    50. ct->replace(idx - User, ttt);[/B]
    51. /* OLD CODE
    52.  
    53.   previousSize = ct->at(idx - User).size;
    54.   previousFlags = ct->at(idx - User).flags;
    55. */
    56. }
    57. }
    58.  
    59. if (idx < User) {
    60. previousSize = QMetaType::sizeOf(idx);
    61. previousFlags = QMetaType::typeFlags(idx);
    62. }
    63.  
    64. if (previousSize != size) {
    65. qFatal("QMetaType::registerType: Binary compatibility break "
    66. "-- Size mismatch for type '%s' [%i]. Previously registered "
    67. "size %i, now registering size %i.",
    68. normalizedTypeName.constData(), idx, previousSize, size);
    69. }
    70.  
    71. // Ignore WasDeclaredAsMetaType inconsitency, to many users were hitting the problem
    72. previousFlags |= WasDeclaredAsMetaType;
    73. flags |= WasDeclaredAsMetaType;
    74.  
    75. if (previousFlags != flags) {
    76. const int maskForTypeInfo = NeedsConstruction | NeedsDestruction | MovableType;
    77. const char *msg = "QMetaType::registerType: Binary compatibility break. "
    78. "\nType flags for type '%s' [%i] don't match. Previously "
    79. "registered TypeFlags(0x%x), now registering TypeFlags(0x%x). "
    80. "This is an ODR break, which means that your application depends on a C++ undefined behavior."
    81. "\nHint: %s";
    82. QT_PREPEND_NAMESPACE(QByteArray) hint;
    83. if ((previousFlags & maskForTypeInfo) != (flags & maskForTypeInfo)) {
    84. hint += "\nIt seems that the type was registered at least twice in a different translation units, "
    85. "but Q_DECLARE_TYPEINFO is not visible from all the translations unit or different flags were used."
    86. "Remember that Q_DECLARE_TYPEINFO should be declared before QMetaType registration, "
    87. "preferably it should be placed just after the type declaration and before Q_DECLARE_METATYPE";
    88. }
    89. qFatal(msg, normalizedTypeName.constData(), idx, previousFlags, int(flags), hint.constData());
    90. }
    91.  
    92. return idx;
    93. }
    To copy to clipboard, switch view to plain text mode 

    Best regards and Merry Christmas to all !

    Hauke

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Is this a bug?

    Hmm... what happens if you call Q_DECLARE_METATYPE more than once on the same type?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Apr 2010
    Posts
    8
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X

    Default Re: Is this a bug?

    hi,

    if you call Q_DECLARE_METATYPE for the second time on the same type, qmetatypestatictype returns a valid id (line 11 in the referenced code from my previous post). in that case, the handler only performs a rather simple test (look at the section highlighted as /* OLD_CODE */ in the code fragment in my previous post, line 51-55 + 64). in particular, the handler is not updated in terms of the callback handlers defined by the bew class declared as a metatype.

    in my modification, this is what i do ( refer to section highlighted by /* NEW_CODE */, line 42-50): update the callback pointers whenever Q_DECLARE_METATYPE is called in adjacent calls.

    best regards

    hauke

  4. #4
    Join Date
    Apr 2013
    Posts
    63
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Is this a bug?

    Has it been fixed? I am still having crash in case of dll

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.