Bug 453065

Summary: memcheck warnings when using C++
Product: [Developer tools] valgrind Reporter: leonardopsantos
Component: memcheckAssignee: Julian Seward <jseward>
Status: RESOLVED NOT A BUG    
Severity: normal CC: tom
Priority: NOR    
Version First Reported In: 3.19.0   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description leonardopsantos 2022-04-26 19:02:13 UTC
A very simple application produces a non-clean valgrind memcheck report for no obvious reason:

`main.cpp`
```
#include <cstdio>

struct s {};

int main (void) {

	struct s value = s();

	const unsigned char* obj_bytes = (const unsigned char*) &value;
	size_t count = sizeof(value);

	printf("[%d %s] count : %ld, obj_bytes : %p\n", __LINE__, __FUNCTION__, count, obj_bytes);
	for (size_t i = 0; i < count; i++) {
	  	printf("%ld: %02x", i, obj_bytes[i]);
	}
	printf("\n");
	

	return 0;
}
```

Compiled with:

```sh
g++ -O0 -g -std=c++11 -Wall -o main main.cpp
```

Generates a very lengthy report and I don't understand why:
```
 VALGRIND_LIB=~/work/googletest/bug/valgrind/src/valgrind-3.19.0/.in_place ~/work/googletest/bug/valgrind/src/valgrind-3.19.0/coregrind/valgrind --track-origins=yes --show-reachable=yes --leak-check=full ./main 
==2544006== Memcheck, a memory error detector
==2544006== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2544006== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==2544006== Command: ./main
==2544006== 
[12 main] count : 1, obj_bytes : 0x1ffefffbaf
==2544006== Use of uninitialised value of size 8
==2544006==    at 0x48C410A: _itoa_word (_itoa.c:180)
==2544006==    by 0x48DF964: __vfprintf_internal (vfprintf-internal.c:1646)
==2544006==    by 0x48CA58E: printf (printf.c:33)
==2544006==    by 0x10921A: main (main.cpp:14)
==2544006==  Uninitialised value was created by a stack allocation
==2544006==    at 0x109189: main (main.cpp:5)
==2544006== 
==2544006== Conditional jump or move depends on uninitialised value(s)
==2544006==    at 0x48C411C: _itoa_word (_itoa.c:180)
==2544006==    by 0x48DF964: __vfprintf_internal (vfprintf-internal.c:1646)
==2544006==    by 0x48CA58E: printf (printf.c:33)
==2544006==    by 0x10921A: main (main.cpp:14)
==2544006==  Uninitialised value was created by a stack allocation
==2544006==    at 0x109189: main (main.cpp:5)
==2544006== 
==2544006== Conditional jump or move depends on uninitialised value(s)
==2544006==    at 0x48E05E3: __vfprintf_internal (vfprintf-internal.c:1646)
==2544006==    by 0x48CA58E: printf (printf.c:33)
==2544006==    by 0x10921A: main (main.cpp:14)
==2544006==  Uninitialised value was created by a stack allocation
==2544006==    at 0x109189: main (main.cpp:5)
==2544006== 
==2544006== Conditional jump or move depends on uninitialised value(s)
==2544006==    at 0x48DFA87: __vfprintf_internal (vfprintf-internal.c:1646)
==2544006==    by 0x48CA58E: printf (printf.c:33)
==2544006==    by 0x10921A: main (main.cpp:14)
==2544006==  Uninitialised value was created by a stack allocation
==2544006==    at 0x109189: main (main.cpp:5)
==2544006== 
0: 00
==2544006== 
==2544006== HEAP SUMMARY:
==2544006==     in use at exit: 0 bytes in 0 blocks
==2544006==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==2544006== 
==2544006== All heap blocks were freed -- no leaks are possible
==2544006== 
==2544006== For lists of detected and suppressed errors, rerun with: -s
==2544006== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
```

I first caught this issue when using Google Test: https://github.com/google/googletest/issues/3805

The C version of pretty much the same code works file:

`main.c`
```
#include <stdio.h>

struct s {};

int main (void) {

	struct s value;

	const unsigned char* obj_bytes = (const unsigned char*) &value;
	size_t count = sizeof(value);

	printf("[%d %s] count : %ld, obj_bytes : %p\n", __LINE__, __FUNCTION__, count, obj_bytes);
	for (size_t i = 0; i < count; i++) {
	  	printf("%ld: %02x", i, obj_bytes[i]);
	}
	printf("\n");
	

	return 0;
}
```

```sh
$ gcc -O0 -g -Wall -o main main.c
```

```
$ VALGRIND_LIB=~/work/googletest/bug/valgrind/src/valgrind-3.19.0/.in_place ~/work/googletest/bug/valgrind/src/valgrind-3.19.0/coregrind/valgrind --track-origins=yes --show-reachable=yes --leak-check=full ./main 
==2544226== Memcheck, a memory error detector
==2544226== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2544226== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==2544226== Command: ./main
==2544226== 
[12 main] count : 0, obj_bytes : 0x1ffefffbaf

==2544226== 
==2544226== HEAP SUMMARY:
==2544226==     in use at exit: 0 bytes in 0 blocks
==2544226==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==2544226== 
==2544226== All heap blocks were freed -- no leaks are possible
==2544226== 
==2544226== For lists of detected and suppressed errors, rerun with: -s
==2544226== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```


STEPS TO REPRODUCE
1. Compile the code example above
2. Run valgrind on the binary

OBSERVED RESULT

Bunch of warnings


EXPECTED RESULT

No warnings


SOFTWARE/OS VERSIONS

valgrind-3.17.0

Operating System: Kubuntu 21.10
KDE Plasma Version: 5.22.5
KDE Frameworks Version: 5.86.0
Qt Version: 5.15.2
Comment 1 Tom Hughes 2022-04-26 19:37:32 UTC
Notice that the size of the struct is 0 in the C version and 1 in the C++ version because C++ has added a single padding byte to the structure.

That padding byte is not initialised, but you are trying to print it, hence the warning.