2014-03-27 2 views
15

uber-easy 개념이라면 유감이지만 clang에서 제공하는 살균제를 올바르게 사용하려면 올바른 사고 방식을 얻는 것이 어렵습니다. ,나는 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) 

그래서 위생 처리 된 버전에는 이것을 컴파일 할 때 사용했던 살균제와 유사한 이름을 가진 정의되지 않은 기호가 있습니다. 하지만 모든 것이 실제로는 "침묵"하고 clang 프론트 엔드에서 전혀 출력되지 않습니다.

어떻게 살균제를 사용해야하고 올바른 워크 플로우는 무엇입니까? 정의되지 않은 심볼의 핵심은 무엇입니까?

+0

프로그램을 실행 파일로 연결하고 실행해야합니다. 살균제는 런타임 도구입니다. – osgx

+0

@osgx 재미있는 점은, 아무도 문서를 컴파일하지 못하고 "main"함수를 사용하여 뭔가를 실행했다는 것을 발견했다는 것입니다 ... 그래서 저는 이것이 컴파일 도구라는 아이디어를 얻었습니다. – user2485710

+0

user2485710, 어느 docs? Clang의 매뉴얼에는 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


컴파일 타임 검사를 원하면 더 많은 컴파일러 경고 또는 정적 분석기를 사용하고 싶습니다. 그러나 부동 소수점 0으로 나누기 오류에 대한 경고 또는 정적 분석 검사가없는 것 같습니다.

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' 
} 
^ 

죽은 가게도 할 수 있습니다 : 그것은 다음과 같은보고

#include <malloc.h> 

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

clang++ -std=c++11 main.cpp로 컴파일이 더 진단을 생산하지 않지만 clang++ -std=c++11 --analyze main.cpp 컴파일 : 여기

는 분석기 보고서를 생성하는 프로그램입니다 - 모든 것 [-Wunused-value]로 감지되었지만 누출은 분석기에서만 감지됩니다.

기본적으로 전체 분석 결과는 plist 파일에 기록됩니다. 또한 명령에 분석을 실행할 수 있습니다

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

대신의 PLIST에, 표준 출력 또는 각각 주석 소스 코드의 HTML 표시를 통해 감지 된 문제에 대한 자세한 워크 스루를 얻을 수 있습니다.

분석기 검사는 here입니다.

분석기가 작동하기 위해서는 분석기가 전체 프로그램을 분석해야한다는 점에 유의해야합니다. 즉, 분석기는 빌드 시스템에 연결해야합니다. 일반적인 인터페이스는 IDE (Xcode) 또는 scan-build 도구를 통해 이루어집니다. CMake는 clang을 생성하는 것과 같은 몇 가지 clang 기능을 가지고 있지만, CMake가 clang 분석기를 지원하도록 빌드되어 있다면 손에서 꺼내지는 못합니다. 우리이 (가) Controlling Code Generation에 설명서를 보면

+0

이것을 컴파일하기 위해 어떤 컴파일러 옵션을 사용 했습니까? – user2485710

+1

@ user2485710'clang ++ -fsanitize = 정의되지 않은 main.cpp &&./a.out' – bames53

+0

그리고 동적 링크 라이브러리가 없습니까? 이것은 나를 위해 작동하지만, 이것에 관련된 llvm 라이브러리가 정적으로 링크되어있는 것처럼 보입니다. – user2485710

6

는 그래서는 말한다 (강조 광산) :

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.

지금이 시간 검사를 컴파일하지 런타임 검사입니다.

runtime error: division by zero

이 예 live-fsanitize=undefined 사용을 참조하십시오 : 당신은 당신의 코드에서 foo를 사용 그렇다면 당신은 다음과 같은 출력을 볼 것입니다

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

:

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

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

두 개의 런타임 메시지를 생성

업데이트

정적 체커와 관련하여 내 대답은 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)에는 정적 체커에 대한 좋은 참고 자료가 있습니다. –

관련 문제