From: Paul F. <pj...@wa...> - 2023-03-28 12:58:24
|
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 |