0

我正在尝试创建共享库(使用 CMake),它在内部使用 Qt 对象(特别是 QString 和 QQueue)并将该库与其他应用程序一起使用。问题是应用程序在调用 QQueue 的方法时收到 SIGSEGV:

(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

你能帮我理解我错在哪里吗?

PS 我正在使用 Qt 4.6.3、Debian Squeeze x86 和 x64、gcc 4.4.5

4

1 回答 1

2

你正在破坏你QQueue的字符串数组的初始化。对于那些(像我一样)在导航您的 Sources/Branches/SubRepositories 时遇到问题的人......您的 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

无关。下一次,在假设相关之前尝试将所有内容构建到单个可执行文件中!:-)

于 2012-06-01T09:09:30.013 回答