C++ 具有未定义行为消毒剂的共享库(clang+;+;)

C++ 具有未定义行为消毒剂的共享库(clang+;+;),c++,clang,llvm,undefined-behavior,C++,Clang,Llvm,Undefined Behavior,我在运行带有dlopen函数的可执行文件时遇到问题,该函数用于使用一个简单的函数打开共享和消毒库 我在Ubuntu 14.04中使用预编译的Clang 3.9.0。 我的问题是:是否可以正确运行它,以便在运行可执行文件时在库中查找未定义的行为错误?如果答案是肯定的,那么如何回答呢 我有两个文件: //simpledll.cpp #include <cstdio> int hehe(int argc) { int k = 0x7fffffff; k +=

我在运行带有dlopen函数的可执行文件时遇到问题,该函数用于使用一个简单的函数打开共享和消毒库

我在Ubuntu 14.04中使用预编译的Clang 3.9.0。

我的问题是:是否可以正确运行它,以便在运行可执行文件时在库中查找未定义的行为错误?如果答案是肯定的,那么如何回答呢

我有两个文件:

//simpledll.cpp
#include <cstdio>

int hehe(int argc) {
      int k = 0x7fffffff;
        k += argc;
          return 0;
}

//dlopen.cpp
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main() {
    void* handle;

    handle = dlopen("simpledll.so", RTLD_LAZY);
    if(!handle) {
        fprintf(stderr, "%s\n", dlerror());
    }

    int (*function)(int) = reinterpret_cast<int (*)(int)> (dlsym(handle, "_Z4hehei"));

    if (function == nullptr)
        fprintf(stderr, "Nope\n");
    else
        function(1000); // this yields signed integer overflow

    return 0;
}
使用以下内容编译库:

clang++ -fsanitize=undefined -shared -o simpledll.so -fPIC simpledll.cpp
clang++ -fsanitize=undefined -shared -Wl,--whole-archive -L/usr/local/lib/clang/3.9.0/lib/linux/ -lclang_rt.ubsan_standalone_cxx-x86_64 -Wl,--no-whole-archive -lclang_rt.ubsan_standalone-x86_64 -Wl,--no-whole-archive -o simpledll.so -fPIC simpledll.cpp
结果:

./dlopen: symbol lookup error: simpledll.so: undefined symbol: __ubsan_handle_add_overflow
==11478==Sanitizer CHECK failed: /home/development/llvm/3.9.0/final/llvm.src/projects/compiler-rt/lib/ubsan/ubsan_init.cc:61 ((UBSAN_MODE_UNKNOWN)) != ((ubsan_mode)) (0, 0)
第二步(由此产生的想法)

按照步骤I编译可执行文件

使用以下内容编译库:

clang++ -fsanitize=undefined -shared -o simpledll.so -fPIC simpledll.cpp
clang++ -fsanitize=undefined -shared -Wl,--whole-archive -L/usr/local/lib/clang/3.9.0/lib/linux/ -lclang_rt.ubsan_standalone_cxx-x86_64 -Wl,--no-whole-archive -lclang_rt.ubsan_standalone-x86_64 -Wl,--no-whole-archive -o simpledll.so -fPIC simpledll.cpp
结果:

./dlopen: symbol lookup error: simpledll.so: undefined symbol: __ubsan_handle_add_overflow
==11478==Sanitizer CHECK failed: /home/development/llvm/3.9.0/final/llvm.src/projects/compiler-rt/lib/ubsan/ubsan_init.cc:61 ((UBSAN_MODE_UNKNOWN)) != ((ubsan_mode)) (0, 0)
请注意,在步骤II中,如果我们将共享库中的函数替换为没有未定义行为代码的函数,则程序运行时不会出现检查失败错误。这表示UBSAN发现了未定义的行为代码,但无法正确报告。

问候,


Jaszczur

什么构成正确的报告?我们应该得到一个运行时错误:有符号整数溢出,因为数字1000+0x7fffffff不能在类型“int”中表示。看起来clang中不支持将清理程序链接到共享库。您可以使用-fsznitize=。。。但您需要将可执行文件与消毒器运行时(-lclang\u rt.ubsan\u standalone-x86\u 64)链接。一旦你这样做了(使用-Wl,-整个档案),你就会得到正确的报告。你能详细说明一下吗?当我像第二步那样编译库并使用以下命令执行时:clang++dlopen.cpp-Wl,--whole archive-L/usr/local/lib/clang/3.9.0/lib/linux/-lclang\u rt.ubsan\u standalone\u cxx-x86\u 64-Wl,--no-whole archive-ldl--std=c++11-o dlopen我仍然无法让它工作,获取了很多未定义的引用到-ubsan:*OK发现了问题,以下是我要做的:(1)构建共享库:
clang++-fPIC-o simpledl.so-fsanizize=undefined simpledl.cpp-shared-std=c++11-stdlib=libc++
(2)构建可执行文件:
clang++-rdynamic-o dlopen dlopen.cpp-std=c++11-stdlib libc++-Wl,-rpath=-L/usr/lib/clang/4.0.1/lib/linux/-Wl,-整个归档文件-lclang\u rt.ubsan\u standalone\u cxx-x86\u 64-lclang\u rt.ubsan\u standalone-x86\u 64-Wl,-没有整个归档文件-stdlib=libc++-pthread-lrt-ldl
(3)错误消息:
simpledl.cpp:3:4:运行时错误:有符号整数溢出:2147483647+1000不能用“int”类型表示。