2017-01-09 2 views
1

주소 소실 기 (clang v3.4)를 사용하여 메모리 누수를 감지 할 때 -O 옵션을 사용하면 항상 누수가 없음을 알았습니다 검출 된 결과. 그러나주소 Sanitizer가 -O 옵션을 사용하여 메모리 누수를 감지 할 수 없음

clang -fsanitize=address -g -O0 main.cpp 

올바르게 메모리를 감지, -O 첨가,

==2978==WARNING: Trying to symbolize code, but external symbolizer is not initialized! 

================================================================= 
==2978==ERROR: LeakSanitizer: detected memory leaks 

Direct leak of 400 byte(s) in 1 object(s) allocated from: 
    #0 0x4652f9 (/home/mrkikokiko/sdk/MemoryCheck/a.out+0x4652f9) 
    #1 0x47b612 (/home/mrkikokiko/sdk/MemoryCheck/a.out+0x47b612) 
    #2 0x7fce3603af44 (/lib/x86_64-linux-gnu/libc.so.6+0x21f44) 

SUMMARY: AddressSanitizer: 400 byte(s) leaked in 1 allocation(s). 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    int* array = (int *)malloc(sizeof(int) * 100); 
    for (int i = 0; i < 100; i++) //Initialize 
    array[i] = 0; 
    return 0; 
} 

때 -O0 컴파일 :

코드는 단순

clang -fsanitize=address -g -O main.cpp 

아무 것도 감지되지 않았습니다! 그리고 나는 공식 문서에서 그것에 대해 아무것도 발견하지 못합니다.

+0

코드는 C 코드가 아닌 C++ 코드입니다. C++ 태그가 잘못되어 C 태그를 사용해야합니다. –

+0

배열을 사용하고 있지 않습니다. 아마도 최적화 된 것입니까? –

+0

@BasileStarynkevitch OP가 C++을 사용하고 있음을 나타내는'clang -fsanitize = address -g -O main.cpp' 라인을 봅니다 (clang 컴파일러는 파일 확장자'.cpp'를 기반으로 언어를 선택합니다). OP의 코드는 유효한 C++입니다. –

답변

5

your code is completely optimized away입니다. 그 결과 어셈블리가 같은 것입니다 : malloc에 대한 호출없이

main:         # @main 
    xorl %eax, %eax 
    retq 

, 더 메모리 할당 ... 따라서 어떤 메모리 누수가 없다.코멘트에 언급

  • Compile with optimizations disabled

    , Simon Kraemer과 같이 위해


    는 당신도 할 수있는, AddressSanitizer는 메모리 누수를 검색 할 수 있습니다.

  • 마크 arrayvolatile, preventing the optimization 같이

    main:         # @main 
         pushq %rax 
         movl $400, %edi    # imm = 0x190 
         callq malloc     # <<<<<< call to malloc 
         movl $9, %ecx 
    .LBB0_1:        # =>This Inner Loop Header: Depth=1 
         movl $0, -36(%rax,%rcx,4) 
         movl $0, -32(%rax,%rcx,4) 
         movl $0, -28(%rax,%rcx,4) 
         movl $0, -24(%rax,%rcx,4) 
         movl $0, -20(%rax,%rcx,4) 
         movl $0, -16(%rax,%rcx,4) 
         movl $0, -12(%rax,%rcx,4) 
         movl $0, -8(%rax,%rcx,4) 
         movl $0, -4(%rax,%rcx,4) 
         movl $0, (%rax,%rcx,4) 
         addq $10, %rcx 
         cmpq $109, %rcx 
         jne  .LBB0_1 
         xorl %eax, %eax 
         popq %rcx 
         retq 
    
+1

아니면 그냥'-O0'로 컴파일하십시오 : https://godbolt.org/g/0ul4bk –

+0

@SimonKraemer : 저는 OP가 메모리 누수가보고 된'-O0'로 컴파일 할 때 이것을 알고 있다고 생각했습니다 바르게. –

+0

그냥 완벽을 위해 그것을 추가하고 싶었 ... –

3

생성 된 코드를 살펴보십시오.

두 가지 모두 GCC & 클랜은 실제로 malloc의 의미에 대해 알고 있습니다. 내 리눅스/데비안 시스템에 <stdlib.h>

extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur; 

__attribute_malloc__ & _wur (및 __THROW)에 포함되어 있기 때문에 매크로는 다른 곳에서 정의된다. 대한 Common Function AttributesGCC documentation, 그리고 연타 문서 says 읽기 :

연타가 GCC 확장의 넓은 범위를 지원하는 것을 목표로하고있다.

나는 강하게 -Omalloc에 대한 호출이 그것을 제거하여을 최적화이라고 생각한다. clang -O -S psbshdk.c (연타 3.8)를 사용하여 내 리눅스/x86-64에 기계 내가 참으로 얻고에서

는 : 주소 소독제는 방출 된 바이너리에 노력하고 있습니다

.globl main 
    .align 16, 0x90 
    .type main,@function 
main:         # @main 
    .cfi_startproc 
# BB#0: 
    xorl %eax, %eax 
    retq 
.Lfunc_end0: 
    .size main, .Lfunc_end0-main 
    .cfi_endproc 

(모든 malloc 전화를 포함하지 것이다) .

현재 clang -O -g으로 컴파일 한 다음 valgrind을 사용하거나 clang -O -fsanitize=address -g으로 컴파일 할 수 있습니다. clang & gcc 둘 다 최적화하고 일부 디버그 정보를 제공 할 수 있습니다 (많은 부분을 최적화 할 때 "근사치"일 수 있음).

관련 문제