2014-03-27 29 views
15

对不起,如果这是一个超级简单的概念,但我很难获得正确的心态,以便正确使用clang提供的消毒剂。我应该如何在叮当中使用消毒剂?

float foo(float f) { return (f/0); } 

我编这个小片段与

clang++ -fsanitize=float-divide-by-zero -std=c++11 -stdlib=libc++ -c source.cpp -o osan 

,我也编译我的对象的“正常”的版本,不使用消毒

clang++ -std=c++11 -stdlib=libc++ -c source.cpp -o onorm 

我期待一些详细的输出,或从控制台的一些错误,但在检查文件与nm我只发现1差异

nm o* --demangle 

onorm: 
0000000000000000 T foo(float) 

osan: 
       U __ubsan_handle_divrem_overflow 
0000000000000000 T foo(float) 

因此,在消毒版本中有一个未定义的符号,其名称类似于编译时使用的消毒剂;但是一切都非常“沉默”,从铿锵声前端没有任何输出。

我应该如何使用清洁剂,什么是正确的工作流程?那个未定义的符号有什么意义?

+0

您应该将您的程序链接到可执行文件并运行它。消毒剂是运行时间的工具。 – osgx

+0

@osgx有趣的是,在我发现没有人编译过的文档中,运行带有'main'函数的东西......所以我开始意识到这是编译时工具。 – user2485710

+0

user2485710,哪些文档?铿锵的手册说:http://clang.llvm.org/docs/UsersManual.html“控制代码生成... -fsanitize = ...打开**运行时检查**各种形式的未定义或可疑的行为...如果检查失败,在运行时会产生一个诊断消息来解释问题。“ – osgx

回答

10

未定义的符号是一个实现清洁剂检查的功能。如果你看一下生成的代码:

没有消毒:

_Z3foof:        # @_Z3foof 
    .cfi_startproc 
# BB#0: 
    xorps %xmm1, %xmm1 
    divss %xmm1, %xmm0 
    ret 

带消毒:

_Z3foof:        # @_Z3foof 
    .cfi_startproc 
    .long 1413876459    # 0x54460aeb 
    .quad _ZTIFffE 
# BB#0: 
    pushq %rax 
.Ltmp1: 
    .cfi_def_cfa_offset 16 
    movss %xmm0, 4(%rsp)   # 4-byte Spill 
    movd %xmm0, %esi 
    movl $__unnamed_1, %edi 
    xorl %edx, %edx 
    callq __ubsan_handle_divrem_overflow 
    xorps %xmm1, %xmm1 
    movss 4(%rsp), %xmm0   # 4-byte Reload 
    divss %xmm1, %xmm0 
    popq %rax 
    ret 

你看它添加的代码做使用该功能的检查。

编译器应在适当的消毒库自动链接,然后我下面的完整的程序:

float foo(float f) { return (f/0); } 
int main() { 
    foo(1.0f); 
} 

可生产执行时的输出如下:我建

main.cpp:1:32: runtime error: division by zero 

,并使用跑指令clang++ -fsanitize=undefined main.cpp && ./a.out


如果您希望编译时检查您希望启用更多编译器警告或静态分析器。但是,似乎没有任何警告或静态分析检查浮点除零错误。

下面是产生一个分析报告的程序:

#include <malloc.h> 

int main() { 
    int *i = (int*) malloc(sizeof(int)); 
} 

clang++ -std=c++11 main.cpp编译它不产生任何诊断,但clang++ -std=c++11 --analyze main.cpp编译它报告如下:

main.cpp:4:10: warning: Value stored to 'i' during its initialization is never read 
    int *i = (int*) malloc(sizeof(int)); 
     ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~ 
main.cpp:5:1: warning: Potential leak of memory pointed to by 'i' 
} 
^ 

死者店也可以用-Weverything [-Wunused-value]检测到,但泄漏只能由分析仪检测到。

默认全分析结果写入plist文件。你也可以用下面的命令运行分析:

clang++ --analyze -Xanalyzer -analyzer-output=text main.cpp 
clang++ --analyze -Xanalyzer -analyzer-output=html -o html-dir main.cpp 

要获得的检测问题进行了详细穿行在标准输出或通过分别的注释的源代码的HTML显示,而不是在plist中。

分析仪检查列表here

请注意,要使分析仪最好地工作,需要分析整个程序,这意味着它需要连接到构建系统。通常的界面是通过IDE(Xcode)或者带有make的scan-build工具。 CMake有一些铿锵声的功能,比如产生叮声号JSON compilation database files,但如果CMake内置了对铛分析器的内置支持,我不确定。

+0

你用什么编译器选项来编译这个? – user2485710

+1

@ user2485710'clang ++ -fsanitize = undefined main.cpp &&。/ a.out' – bames53

+0

并且您没有获得动态链接库?这适用于我,但它看起来像这个静态链接的llvm库。 – user2485710

6

所以,如果我们在该Controlling Code Generation看文档,它说(重点煤矿):

Turn on runtime checks for various forms of undefined or suspicious behavior.

This option controls whether Clang adds runtime checks for various forms of undefined or suspicious behavior, and is disabled by default. If a check fails, a diagnostic message is produced at runtime explaining the problem.

所以这些都是运行时检查不编译时检查。所以,如果你在你的代码中使用foo那么你会看到下面的输出:

runtime error: division by zero

请参阅使用-fsanitize=undefined这个例子live

float foo(float f) { return (f/0); } 

int main() 
{ 
    int x = 1 << 100 ; 
    foo(2.0f) ; 
} 

它生成两个运行时提示:

main.cpp:6:19: runtime error: shift exponent 100 is too large for 32-bit type 'int'

main.cpp:2:36: runtime error: division by zero

更新

关于静态检查器,在我对A C++ implementation that detects undefined behavior?的回答中,我提到了几个工具:STACK,kcc,当然还有Frama-C

显然clang允许您使用--analyze to run it's static checker,但它似乎最终可能会被禁用,正确的方式来运行它将通过scan-build

同样在我的自我回答问题Why do constant expressions have an exclusion for undefined behavior?我演示了如何在编译时使用constexprs来捕获未定义的行为。

+1

啊,是的。如果他期待编译时间检查,那么消毒剂是错误的工具。静态分析器执行更多的编译时检查。 – bames53

+0

现在我理解了这一点,但我仍然认为它可能对更详细的输出更有用。什么是llvm/clang的静态分析参考? – user2485710

+0

@ user2485710我对[检测未定义行为的C++实现?](http://stackoverflow.com/a/21388572/1708801)的答案对静态检查器有一些很好的参考。 –