Ошибка сегментации при использовании QQueue::enqueue()

Я пытаюсь создать общую библиотеку (с CMake), которая использует объекты Qt (в частности, QString и QQueue) внутри и использует эту библиотеку с другим приложением. Проблема в том, что приложение получает SIGSEGV при вызове методов QQueue:

(gdb) r
Starting program: /home/ilya/projects/qtLogger/build/qtLoggerSample
[Thread debugging using libthread_db enabled]
startup
_DEBUG
QtLogger::QtLogger()
void QtLogger::foo(void*)
void QtLogger::log(QtLogger::LOG_LEVEL, QString) lvl: DEBUGmsg: "debug 1"

Program received signal SIGSEGV, Segmentation fault.
0x08049450 in QString (this=0x2817ad9c, other=...) at /usr/include/qt4/QtCore/qstring.h:714
714     inline QString::QString(const QString &other) : d(other.d)
(gdb) bt
#0  0x08049450 in QString (this=0x2817ad9c, other=...) at /usr/include/qt4/QtCore/qstring.h:714
#1  0xb7fdda0c in QList<QString>::node_construct (this=0x804b474, n=0x2817ad9c, t=...) at /usr/include/qt4/QtCore/qlist.h:352
#2  0xb7fdd7fa in QList<QString>::append (this=0x804b474, t=...) at /usr/include/qt4/QtCore/qlist.h:481
#3  0xb7fdd5e0 in QQueue<QString>::enqueue (this=0x804b474, t=...) at /usr/include/qt4/QtCore/qqueue.h:59
#4  0xb7fdd19f in QtLogger::log (this=0x804b460, level=QtLogger::LL_DEBUG, message=...)
    at /home/ilya/projects/qtLogger/lib-qtLogger/src/libqtlogger.cpp:97
#5  0x08049099 in main (argc=1, argv=0xbffff644) at    /home/ilya/projects/qtLogger/src/main.cpp:27

Исходный код приложения можно найти здесь: https://github.com/ilardm/qtLoggerSample/tree/137adee556f41eb4526e1d1c604e8541ef6eb65a

Исходный код библиотеки можно найти здесь (также доступен как подмодуль git репозитория приложений): https://github.com/ilardm/lib-qtLogger/tree/bf1b490fd7c6666176c23e6fd791c00937d954b4

Не могли бы вы помочь мне понять, где я ошибаюсь?

P.S. Я использую Qt 4.6.3, Debian Squeeze x86 и x64, gcc 4.4.5.


person ilardm    schedule 01.06.2012    source источник
comment
Если я что-то не упустил, ни в одном из репозиториев, на которые вы ссылаетесь, нет QQueue или QList.   -  person HostileFork says dont trust SE    schedule 01.06.2012
comment
Примечание. Похоже, что ваша основная ветка не обновлена, ваш соответствующий код находится в ядре. github.com/ilardm/lib-qtLogger/blob/core/ inc/libqtlogger.h   -  person HostileFork says dont trust SE    schedule 01.06.2012
comment
Текущий код @HostileFork находится в ядре ветки, но в репозитории приложения используется правильная версия. просто для уточнения   -  person ilardm    schedule 01.06.2012


Ответы (1)


Вы портите свой QQueue своей инициализацией массива строк. Для тех, у кого (как и у меня) возникают проблемы с навигацией по вашим источникам/веткам/подрепозиториям... ваше объявление QtLogger выглядит так:

class LIBQTLOGGER_EXPORT QtLogger
{
public:
    typedef enum {
        LL_EROR,
        LL_WARNING,
        LL_LOG,
        LL_DEBUG,

        LL_COUNT
    } LOG_LEVEL;

public:
    QtLogger();
    ~QtLogger();

public:
    void foo( void* );

    void log( LOG_LEVEL, QString );

protected:
    LOG_LEVEL currentLevel;
    QString ll_string[ LL_COUNT ];

    QQueue< QString > messageQueue;
    QMutex mqMutex;
};

И тогда ваш конструктор выглядит так:

QtLogger::QtLogger()
    : currentLevel( LL_DEBUG )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << __PRETTY_FUNCTION__ << std::endl;
#endif

    ll_string[ LL_EROR      ].sprintf( "ERROR" );
    ll_string[ LL_WARNING   ].sprintf( "WARN " );
    ll_string[ LL_LOG       ].sprintf( "LOG  " );
    ll_string[ LL_DEBUG     ].sprintf( "DEBUG" );

    ll_string[ LL_COUNT     ].sprintf( "     " );
}

LL_EROR равен 0, LL_COUNT равен 4. (Примечание: это слово пишется как "ERROR", поэтому ваша строка является правильным битом.) В любом случае... ваше объявление фактически QString ll_string[4];, в которое вы помещаете 5 строки и повреждение последующей переменной-члена.

Почему вы поместили туда эту пустую строку, во-первых, для меня немного загадка... (!) Но в любом случае, векторные классы довольно легкие в схеме вещей, а не необработанные массивы, и часто предоставляют больше проверка границ для общих операций. Используйте QVector (или что-то еще) в будущем, и будет легче поймать этот класс ошибок:

http://qt-project.org/doc/qt-4.8/qvector.html

Короче говоря, это не имеет ничего общего с shared- библиотеки. В следующий раз попробуйте собрать все в один исполняемый файл, прежде чем предполагать, что это актуально! :-)

person HostileFork says dont trust SE    schedule 01.06.2012
comment
Кроме того, это не имеет ничего общего с cmake! Я уберу эти теги и дам этому более подходящее название (для людей, которые могут прийти сюда через поиск Google в будущем...) - person HostileFork says dont trust SE; 01.06.2012
comment
О боже.. Вы правы. Спасибо. P.S. LL_EROR — это просто опечатка. Полагаю, я был слишком усталым и сонным, пока писал этот код. - person ilardm; 01.06.2012
comment
+1 очень хороший улов! @IlyaArefiev, если вы принимаете это, вы также должны проголосовать за него: stackoverflow.com/faq#howtoask - person Brady; 01.06.2012
comment
Рад, что смог помочь, и не беспокойтесь, мой русский ужасен, даже когда я бодрствую. @Брэди Можно было подумать, что мне платят за такие вещи, но... мне нравится помогать детям. :) hostilefork.com/2012/01/18/stackoverflow-summaries-2011 - person HostileFork says dont trust SE; 01.06.2012