https://bugs.kde.org/show_bug.cgi?id=457860
Bug ID: 457860
Summary: Memcheck classifies leaks differently depending on if
a C program exits with `return` or `exit`
Product: valgrind
Version: 3.18.1
Platform: Ubuntu Packages
OS: Linux
Status: REPORTED
Severity: minor
Priority: NOR
Component: memcheck
Assignee: jsew...@acm.org
Reporter: dylanbbbrot...@gmail.com
Target Milestone: ---
Memcheck classifies leaks differently depending on if a C program exits with
`return` or `exit`
Given this very simple C program in `test_return.c`
```C
#include
#include
int main(void)
{
double *a = malloc(100);
return 0;
}
```
The following output is given
```bash
$ gcc -O0 -g test_return.c -o test_return
$ valgrind -s --leak-check=full --show-leak-kinds=all ./test_return
==26141== Memcheck, a memory error detector
==26141== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26141== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==26141== Command: ./test_return
==26141==
==26141==
==26141== HEAP SUMMARY:
==26141== in use at exit: 100 bytes in 1 blocks
==26141== total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==26141==
==26141== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1
==26141==at 0x4848899: malloc (vg_replace_malloc.c:381)
==26141==by 0x10915E: main (test_return.c:6)
==26141==
==26141== LEAK SUMMARY:
==26141==definitely lost: 100 bytes in 1 blocks
==26141==indirectly lost: 0 bytes in 0 blocks
==26141== possibly lost: 0 bytes in 0 blocks
==26141==still reachable: 0 bytes in 0 blocks
==26141== suppressed: 0 bytes in 0 blocks
==26141==
==26141== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
```
But when given this slightly different program in `test_exit.c`
```C
#include
#include
int main(void)
{
double *a = malloc(100);
exit(0);
}
```
Instead we get
```bash
$ gcc -O0 -g test_exit.c -o test_exit
$ valgrind -s --leak-check=full --show-leak-kinds=all ./test_exit
==26180== Memcheck, a memory error detector
==26180== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26180== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==26180== Command: ./test_exit
==26180==
==26180==
==26180== HEAP SUMMARY:
==26180== in use at exit: 100 bytes in 1 blocks
==26180== total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==26180==
==26180== 100 bytes in 1 blocks are still reachable in loss record 1 of 1
==26180==at 0x4848899: malloc (vg_replace_malloc.c:381)
==26180==by 0x10917E: main (test_exit.c:6)
==26180==
==26180== LEAK SUMMARY:
==26180==definitely lost: 0 bytes in 0 blocks
==26180==indirectly lost: 0 bytes in 0 blocks
==26180== possibly lost: 0 bytes in 0 blocks
==26180==still reachable: 100 bytes in 1 blocks
==26180== suppressed: 0 bytes in 0 blocks
==26180==
==26180== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```
The difference being that with `return` the leak is classifies as "definitely
lost"
but with `exit` the leak is classifies as "still reachable"
even though these programs are identical.
According to section 5.1.2.2.3 of the C specification:
If the return type of the main function is a type compatible with int, a return
from the initial call to the main function is equivalent to calling the exit
function with the value returned by the main function as its argument; [...]
This means that the two above programs should be equivalent and thus behave in
the same manner.
Linux 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 x86_64
x86_64 x86_64 GNU/Linux
Full `-v` ouptut
test_exit.c
```
==26307== Memcheck, a memory error detector
==26307== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26307== Using Valgrind-3.18.1-42b08ed5bd-20211015 and LibVEX; rerun with -h
for copyright info
==26307== Command: ./test_exit
==26307==
--26307-- Valgrind options:
--26307---v
--26307---s
--26307----leak-check=full
--26307----show-leak-kinds=all
--26307-- Contents of /proc/version:
--26307-- Linux version 5.4.72-microsoft-standard-WSL2 (oe-user@oe-host) (gcc
version 8.2.0 (GCC)) #1 SMP Wed Oct 28 23:40:43 UTC 2020
--26307--
--26307-- Arch and hwcaps: AMD64, LittleEndian,
amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand-rdseed
--26307-- Page sizes: currently 4096, max supported 4096
--26307-- Valgrind library directory: /usr/libexec/valgrind
--26307-- Reading syms from /tmp/tmp.wURL71ZPmz/test_exit
--26307-- Reading syms from /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
--26307-- Considering
/usr/lib/debug/.build-id/61/ef896a699bb1c2e4e231642b2e1688b2f1a61e.debug ..
--26307-- .. build-id is valid
--26307-- Reading syms from /usr/libexec/valgrind/memcheck-amd64-linux
--26307--