Bug 419230 - Memcheck does not report conditional jump on uninitialized value
Summary: Memcheck does not report conditional jump on uninitialized value
Status: RESOLVED NOT A BUG
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: 3.15 SVN
Platform: Manjaro Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-03-25 14:00 UTC by Thomas Fannes
Modified: 2020-03-25 14:18 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Minimal example (749 bytes, application/gzip)
2020-03-25 14:00 UTC, Thomas Fannes
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Fannes 2020-03-25 14:00:31 UTC
Created attachment 127003 [details]
Minimal example

SUMMARY

Memcheck does not always report a conditional jump based on an uninitialized value on the stack, but is seems to depend on previous stack allocations.

In attachment a minimal example to reproduce the error. Compiling with macros
INIT_BUFFER=1, TEST_A1=0 and TEST_A2=1, and executing with valgrind will not report the conditional jump based on uninitialized value.

STEPS TO REPRODUCE
1. Allocate a buffer of 1kB on the stack, clear it and let it go out of scope
2. Allocate a struct on the stack (without initialization), but do not use it
3. Allocate a second struct on the stack (without initialization), and jump based on a member.

OBSERVED RESULT
No error is reported

EXPECTED RESULT
Valgrind should report an conditional jump based on unitialized value

SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Manjaro
(available in About System)
KDE Plasma Version: 5.18.3
KDE Frameworks Version:  5.68.0
Qt Version: 4.14.1

ADDITIONAL INFORMATION

compiled with gcc version 9.3.0 (Arch Linux 9.3.0-1)
Comment 1 Tom Hughes 2020-03-25 14:12:56 UTC
That's clearly not a minimal test case because it has a whole pile of ifdefs only one combination of which is required and it is unnecessarily split over multiple files...
Comment 2 Tom Hughes 2020-03-25 14:18:43 UTC
I'm pretty sure that there's no bug here anyway, it's just you're expecting more of valgrind than it is able to provide.

When stack is reused for different variables inside the same function there is no guarantee that the compiler will actually move the stack pointer up at the end of one scope and then back down at the start of the next one - more likely it will just move it down once at the start of the function to reserve the maximum amount of memory required and then move it back at the end.

Within the function it will just use whatever regions it wants within that chunk of stack it has reserved and reuse things as and when it wants.

In fact you don't even need scopes - if you just stop using one variable and start using another then the compiler might decide to overlay them in the same way.

What all this means is that there is no way for valgrind to know when the compiler has switched from using that piece of stack for one variable to using it for another variable and hence no way for it to mark it as uninitialised again. Only at the end of the function when the stack is released by moving the stack pointer will valgrind mark it as uninitialised again.

In general you will find that something like address sanitiser can do a better job finding stack related issues because it is able to instrument at compile time - valgrind is better than nothing for sure but it can never do everything that compile time instrumentation can do.