Why valgrind does not detect a leak when the program was compiled with gcc-5.2.0

Today I encoded something, and after I finished, I checked with valgrindand I got a surprise.

If I compile my program on my Ubuntu (15.04 64BIT) with gcc-4.9.2 with the following:

gcc -Wextra -Werror -Wstrict-prototypes -Wconversion --std=c11 -O2 -g program.c -o program

And then run valgrind:

valgrind --leak-check=full --track-origins=yes ./program

I get the following output:

==5325== Memcheck, a memory error detector
==5325== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5325== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5325== Command: ./program
==5325== 
Bye
==5325== 
==5325== HEAP SUMMARY:
==5325==     in use at exit: 33 bytes in 1 blocks
==5325==   total heap usage: 1 allocs, 0 frees, 33 bytes allocated
==5325== 
==5325== 33 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5325==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5325==    by 0x4004BD: main (program.c:11)
==5325== 
==5325== LEAK SUMMARY:
==5325==    definitely lost: 33 bytes in 1 blocks
==5325==    indirectly lost: 0 bytes in 0 blocks
==5325==      possibly lost: 0 bytes in 0 blocks
==5325==    still reachable: 0 bytes in 0 blocks
==5325==         suppressed: 0 bytes in 0 blocks
==5325== 
==5325== For counts of detected and suppressed errors, rerun with: -v
==5325== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

As you can see, a leak has been detected, but see what happens if I compile gcc-5.2.0 with the following:

./install/gcc-5.2.0/bin/gcc5.2 -Wextra -Werror -Wstrict-prototypes -Wconversion --std=c11 -O2 -g program.c -o program

And now valgrind says:

==5344== Memcheck, a memory error detector
==5344== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5344== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5344== Command: ./program
==5344== 
Bye
==5344== 
==5344== HEAP SUMMARY:
==5344==     in use at exit: 0 bytes in 0 blocks
==5344==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5344== 
==5344== All heap blocks were freed -- no leaks are possible
==5344== 
==5344== For counts of detected and suppressed errors, rerun with: -v
==5344== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

As you can see, there is a common use of the heap: 0 allocs, 0 frees, 0 bytes allocated

The piece of code I tried was as follows:

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

int main(void){
    int a = 0;
    size_t len1 = 0, len2 = 0;
    char *string1 = "Hello";
    char *string2;

    string2 = malloc(33);
    strcpy(string2, "Hello");

    len1 = strlen(string1);
    len2 = strlen(string2);

    if(len1 != len2){
        a = 5;
    }else{
        a=4;
    }

    while (a != -1){
        if(a == 2){
            break;
        }
        a--;
    }


    printf("Bye\n");
    /*free(string2);*/
    return 0;
}

GCC-5.2.0 was installed using this method .

: GCC valgrind? ?

, :

printf("Bye\n");

:

printf("String2 = %s\n",string2);

:

==5443== Memcheck, a memory error detector
==5443== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5443== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5443== Command: ./program
==5443== 
String2 = Hello
==5443== 
==5443== HEAP SUMMARY:
==5443==     in use at exit: 33 bytes in 1 blocks
==5443==   total heap usage: 1 allocs, 0 frees, 33 bytes allocated
==5443== 
==5443== 33 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5443==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5443==    by 0x40044D: main (program.c:11)
==5443== 
==5443== LEAK SUMMARY:
==5443==    definitely lost: 33 bytes in 1 blocks
==5443==    indirectly lost: 0 bytes in 0 blocks
==5443==      possibly lost: 0 bytes in 0 blocks
==5443==    still reachable: 0 bytes in 0 blocks
==5443==         suppressed: 0 bytes in 0 blocks
==5443== 
==5443== For counts of detected and suppressed errors, rerun with: -v
==5443== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

, ? - printf() .

+2
2

, GCC 5.2.0 , string2 "Hello" strcpy. string2, HEAP. , string.h strcpy strlen .

. -O0 -O2. .

:

printf ( "String2 =% s\n", string2);

:

, string2, . , printf , , , printf . ...

+2

C ?, valgrind -O2, . ? :

string2 = malloc(33);
strcpy (string2, "Hello");
...
printf("Bye\n");

string2 "Hello" sting2, string2 . , string2 , , .

"" , , , . , string2, , , .

(, , printf string2, , , printf string2)

, , , (gcc -S , -masm=intel, intel ATT)

-O0. :

    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov     rbp, rsp
    .cfi_def_cfa_register 6
    sub     rsp, 48
    mov     DWORD PTR [rbp-4], 0
    mov     QWORD PTR [rbp-16], 0
    mov     QWORD PTR [rbp-24], 0
    mov     QWORD PTR [rbp-32], OFFSET FLAT:.LC0
    mov     QWORD PTR [rbp-40], 0
    mov     edi, 33
    call    malloc                  ; the call to malloc is retained
    mov     QWORD PTR [rbp-40], rax
    mov     rax, QWORD PTR [rbp-40]
    mov     DWORD PTR [rax], 1819043144
    mov     WORD PTR [rax+4], 111
    mov     rax, QWORD PTR [rbp-32]
    mov     rdi, rax
    call    strlen
    mov     QWORD PTR [rbp-16], rax
    mov     rax, QWORD PTR [rbp-40]
    mov     rdi, rax
    call    strlen
    mov     QWORD PTR [rbp-24], rax
    mov     rax, QWORD PTR [rbp-16]
    cmp     rax, QWORD PTR [rbp-24]
    je      .L2
    mov     DWORD PTR [rbp-4], 5
    jmp     .L4

( gcc (GCC) 6.1.1 20160602 -Ofast):

    .cfi_startproc
    sub     rsp, 8
    .cfi_def_cfa_offset 16
    mov     edi, OFFSET FLAT:.LC0
    call    puts
    xor     eax, eax
    add     rsp, 8
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc

malloc - . , , .

, valgrind , , valgrind , . , , - , /, , , - . , :

gcc -S -masm=intel -Ofast -o valgrindtest.asm valgrindtest.c

valgrindtest.asm. , .

+2

Source: https://habr.com/ru/post/1654561/


All Articles