0

内部で Qt オブジェクト (特に QString と QQueue) を使用する共有ライブラリ (CMake を使用) を作成し、このライブラリを他のアプリケーションで使用しようとしています。問題は、アプリケーションが 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文字列配列の初期化で破損しています。(私のように)ソース/ブランチ/サブリポジトリのナビゲートに問題がある人のために... 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 ですQString ll_string[4];

そもそもなぜその空の文字列をそこに入れるのかは、私には少し謎です... (!) しかし、いずれにせよ、ベクトルクラスは生の配列ではなく物事のスキームにおいてかなり軽量であり、しばしばより多くを提供します一般的な操作の境界をチェックします。将来的に(または何でも)使用するQVectorと、このクラスのバグを見つけやすくなります。

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

とは何の関係もありません。次回は、関連性があると思い込む前に、すべてを単一の実行可能ファイルにビルドしてみてください。:-)

于 2012-06-01T09:09:30.013 に答える