[valgrind] [Bug 457860] Memcheck classifies leaks differently depending on if a C program exits with `return` or `exit`

2022-08-13 Thread Dylan Brotherston
https://bugs.kde.org/show_bug.cgi?id=457860

Dylan Brotherston  changed:

   What|Removed |Added

 CC||dylanbbbrot...@gmail.com

-- 
You are receiving this mail because:
You are watching all bug changes.

[valgrind] [Bug 457860] New: Memcheck classifies leaks differently depending on if a C program exits with `return` or `exit`

2022-08-13 Thread Dylan Brotherston
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--