|
From: Jefferson C. <jef...@gm...> - 2020-08-09 08:13:41
Attachments:
test.c
|
After performing this sort of operation, valgrind raises a false
positive that x is either uninitialized or an invalid read, depending on
whether the stack pointer is moved from above x to below it, or from
below to above.
--------------------x-----------------------
^ esp
--------------------x-----------------------
^ esp
I've attached a code sample that demonstrates this. Compile in -m32
mode and run under valgrind, and it complains that x is uninitialized,
even thought it contains the value it is initialized to.
(Swap '0x1000' and '-0x1000' in the assembly section and the message
will alternate between 'conditional jump depends on uninitialized value'
and 'invalid read')
I know valgrind has various heuristics having to do with the stack the
program appears to be using (it does say "Warning: client switching
stacks?"). However, I'm planning to try to find the place in the
valgrind code where the memory is marked as dirty and fix it. If it
seems like a good fix, I might send in a patch.
I'm sending this email to A) let you know that I'm doing this - how
quickly it gets done will depend on many things including what other
projects I have going on, and my motivation - and B) in case you have
any advice or wisdom to share.
-Jefferson
|
|
From: Tom H. <to...@co...> - 2020-08-09 08:55:47
|
On 09/08/2020 09:13, Jefferson Carpenter wrote: > After performing this sort of operation, valgrind raises a false > positive that x is either uninitialized or an invalid read, depending on > whether the stack pointer is moved from above x to below it, or from > below to above. This is just valgrind's normal operation - it's how it knows when a stack variable goes out of scope by looking to see when the stack pointer moves up and invalidating those variables which are now below it. Even if you think you have some clever code that has a use for referring to something below the stack pointer that code is not actually safe because if a signal is delivered while the stack pointer is above the variable then the variable may get overwritten. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: John R. <jr...@bi...> - 2020-08-09 12:54:05
|
> I've attached a code sample that demonstrates this. Compile in -m32 mode and run under valgrind, and it complains that x is uninitialized, even thought it contains the value it is initialized to. X86_64 (-m64) has the software convention that the half-open interval [ -0x80(%rsp), 0(%rsp) ) is "protected". This area is known as the "red zone", and both the compilers and the signal handlers know what to do. The red zone exists so that compiled code can use that area without adjusting the stack pointer %rsp, thus saving two instructions. However, i686 code (-m32) has no red zone. If an address is below the stack pointer %esp then it is NOT protected. As Tom explains, the delivery of a signal can overwrite anything that is below %esp. Thus memcheck is correct; your code has a bug. |