Re: about a stack fill option (as for malloc-fill and free-fill)

Paul Floyd <[email protected]> Tue, 28 Mar 2023 14:58:14 +0200
Newsgroups gmane.comp.debugging.valgrind
Message-ID <[email protected]>

On 28-03-23 11:40, Julien Allali wrote:
> Hi,
> 
>      Sometimes, valgrind detects error like "Conditional jump or move 
> depends" or "Use of uninitialized value" related to a variable in heap. 
> When using with gdb (--vgdb-error=1), a newbie (i.e. my students) can 
> have difficulties to understand as the value stored is 0 (because there 
> was zeros in heap, not because we set 0 to the variable).
> 
>      Could it be possible to add an option like --heap-up-fill 
> --heap-down-fill (like for stack with malloc), that fills heap memory 
> with a specified values (when entering a function and leave a function)?
> 
> Would it be complicated to implement?


Hi

tl;dr

I recommend using the vgdb monitor commands, they show what memcheck 
considers initialized or not. You just have to type something like

"memcheck monitor xb &var sizeof(var)"


tl;dr 2

See
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2723r0.html





Having a "stack  fill" in Valgrind would be very difficult. The problem 
is identifying exactly what is a stack allocation. Identifying a call to 
malloc is easy - we have the address of the function. Stack allocation 
is, roughly, just modifying the stack pointer.


The simplest case is where the callee does the stack allocation, on 
amd64 something like


   201910:       55                      push   %rbp
   201911:       48 89 e5                mov    %rsp,%rbp
   201914:       48 83 ec 10             sub    $0x10,%rsp


where the constant in the last line depends on the amount being 
allocated.  The initial push and move won't be there for optimized 
builds or if -fomit-frame-pointer is specified.

If the compiler is doing RVO then the stack memory will be allocated by 
the caller. See here

https://godbolt.org/z/qasjWGhsK

Line 25 in the asm output is where main allocates the space on the stack.

Then there is tail-call optimization where there is no call, just a jump 
to the callee. And then all of the other things that manipulate the 
stack pointer (alloca, C++ exceptions, signals, setjmp/longjmp). There 
are a few compiler options that affect stack use. On top of all that 
each compiler tends to do things differently.

I don't know what would be possible with DWARF, but that would only work 
with debug builds.

Going back to my second tl;dr

If I compile the godbolt example with

clang++-devel -ftrivial-auto-var-init=pattern jfb.cpp -o jfb

(that's LLVM 16)

then I get

   2019a2:       be aa 00 00 00          mov    $0xaa,%esi
   2019a7:       ba 00 10 00 00          mov    $0x1000,%edx
   2019ac:       e8 bf 00 00 00          call   201a70 <memset@plt>
   2019b1:       48 8d bd 00 f0 ff ff    lea    -0x1000(%rbp),%rdi
   2019b8:       e8 73 ff ff ff          call   201930 <_Z1fv>

which is the caller filling the 4k with 0xaa.



A+
Paul


_______________________________________________
Valgrind-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-users