为什么-fsanitize =未定义的原因"对typeinfo的未定义引用"?

时间:2016-05-21 03:29:30

标签: c++ qt gcc shared-libraries ubsan

以下测试用例(从实际应用程序中删除)无法与-fsanitize=undefined(使用GCC 6.1.1)链接,但没有它就链接正常。谁能告诉我为什么?

它似乎与Qt / QObject,-fvisibility=hidden-fsanitize=undefined的组合有关,但问题所在的确切位置超出了我。

lib1.h:

#include <QObject>

class MyObject : public QObject
{
public:
    MyObject (QObject * parent = nullptr);
    ~MyObject ();

    void myMethod ();
};

lib1.cc:

#include "lib1.h"

#define EXPORT __attribute__((visibility("default")))

EXPORT MyObject::MyObject (QObject * parent) : QObject (parent)
{
}

EXPORT MyObject::~MyObject ()
{
}

EXPORT void MyObject::myMethod ()
{
}

lib2.cc:

#include "lib1.h"

void test (MyObject * object)
{
    object->myMethod ();
}

构建步骤:

LIBFLAGS="-fPIC -shared -Wall -Wl,-z,defs"
QTFLAGS="-I/usr/include/qt -I/usr/include/qt/QtCore -lQt5Core"

g++ -fsanitize=undefined -fvisibility=hidden \
 ${QTFLAGS} ${LIBFLAGS} lib1.cc -o lib1.so

g++ -fsanitize=undefined \
 ${QTFLAGS} ${LIBFLAGS} lib1.so lib2.cc -o lib2.so

构建输出(从最后一步开始):

/tmp/ccY7PHv4.o:(.data.rel+0x18): undefined reference to `typeinfo for MyObject'
collect2: error: ld returned 1 exit status

2 个答案:

答案 0 :(得分:4)

问到的实际问题的答案是-fsanitize=undefined实际上是一系列消毒剂,包括vptr消毒剂。

https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

vptr清洁剂明确标记为需要RTTI,其他答案已说明为什么它不可用。

要运行除 vptr之外的所有测试,您可以说

-fsanitize=undefined -fno-sanitize=vptr

答案 1 :(得分:2)

我认为-fsanitize=undefined是一个红色的鲱鱼。

您只导出该类的成员函数。为了也导出其元数据(如typeinfo和潜在的v-table指针),您需要导出

试试这个

class EXPORT MyObject : public QObject
{
public:
    MyObject (QObject * parent = nullptr);
    ~MyObject ();

    void myMethod ();
};

然后您不需要标记各个成员函数。