|
From: Paul-Antoine A. <li...@de...> - 2020-01-14 17:32:08
|
Hi all, I'm stumbling upon a weird message from Valgrind when run on my application as follows: $ valgrind --vgdb=yes --vgdb-error=0 --undef-value-errors=no $my_app So Valgrind reports: ==1644== Thread 9: ==1644== Invalid read of size 8 ==1644== at 0x4A39B40: PR_int__give_lang_env_for_slave (PR__int.c:348) ==1644== Address 0x12d152c8 is 24 bytes inside a block of size 104 alloc'd ==1644== at 0x483577F: malloc (vg_replace_malloc.c:309) ==1644== by 0x4A3C4B4: [...] I struggle to understand how a read into a block of properly alloc'd memory can be invalid, given that the application doesn't use client requests. To be sure, I double-checked the status of the entire buffer under vgdb: (gdb) mo xb 0x12d152b0 104 [...] Address 0x12D152B0 len 104 has 104 bytes unaddressable How can a block of dynamically-allocated memory be marked unaddressable without having been freed? Thanks in advance for your help! -- Paul-Antoine Arras |
|
From: Tom H. <to...@co...> - 2020-01-14 18:51:58
|
On 14/01/2020 16:53, Paul-Antoine Arras wrote: > I'm stumbling upon a weird message from Valgrind when run on my > application as follows: > > $ valgrind --vgdb=yes --vgdb-error=0 --undef-value-errors=no $my_app > > So Valgrind reports: > > ==1644== Thread 9: > ==1644== Invalid read of size 8 > ==1644== at 0x4A39B40: PR_int__give_lang_env_for_slave (PR__int.c:348) > ==1644== Address 0x12d152c8 is 24 bytes inside a block of size 104 alloc'd > ==1644== at 0x483577F: malloc (vg_replace_malloc.c:309) > ==1644== by 0x4A3C4B4: [...] > > I struggle to understand how a read into a block of properly alloc'd > memory can be invalid, given that the application doesn't use client > requests. > To be sure, I double-checked the status of the entire buffer under vgdb: > > (gdb) mo xb 0x12d152b0 104 > [...] > Address 0x12D152B0 len 104 has 104 bytes unaddressable > > How can a block of dynamically-allocated memory be marked unaddressable > without having been freed? By using the VALGRIND_MAKE_MEM_NOACCESS macro. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Paul-Antoine A. <li...@de...> - 2020-01-14 19:11:10
|
Le 14/01/2020 à 19:51, Tom Hughes a écrit : > On 14/01/2020 16:53, Paul-Antoine Arras wrote: > [...] >> I struggle to understand how a read into a block of properly alloc'd >> memory can be invalid, given that the application doesn't use client >> requests. [...] >> How can a block of dynamically-allocated memory be marked >> unaddressable without having been freed? > > By using the VALGRIND_MAKE_MEM_NOACCESS macro. > Sure, but as I mentioned in my message, the application code does not use client requests. |
|
From: Tom H. <to...@co...> - 2020-01-14 19:01:39
|
On 14/01/2020 18:55, Paul-Antoine Arras wrote: > Le 14/01/2020 à 19:51, Tom Hughes a écrit : >> On 14/01/2020 16:53, Paul-Antoine Arras wrote: >> > [...] >>> I struggle to understand how a read into a block of properly alloc'd >>> memory can be invalid, given that the application doesn't use client >>> requests. > [...] >>> How can a block of dynamically-allocated memory be marked >>> unaddressable without having been freed? >> >> By using the VALGRIND_MAKE_MEM_NOACCESS macro. >> > > Sure, but as I mentioned in my message, the application code does not > use client requests. Using it as a thread stack could also do it, though it looks a bit small for that, or some sort or whacky stack pointer stunts that lead to valgrind thinking it's part of the stack. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |
|
From: Paul-Antoine A. <li...@de...> - 2020-01-14 19:15:52
|
Le 14/01/2020 à 20:01, Tom Hughes a écrit : > On 14/01/2020 18:55, Paul-Antoine Arras wrote: >> Le 14/01/2020 à 19:51, Tom Hughes a écrit : >>> On 14/01/2020 16:53, Paul-Antoine Arras wrote: >>> >> [...] >>>> I struggle to understand how a read into a block of properly alloc'd >>>> memory can be invalid, given that the application doesn't use client >>>> requests. >> [...] >>>> How can a block of dynamically-allocated memory be marked >>>> unaddressable without having been freed? >>> >>> By using the VALGRIND_MAKE_MEM_NOACCESS macro. >>> >> >> Sure, but as I mentioned in my message, the application code does not >> use client requests. > > Using it as a thread stack could also do it, though it looks a > bit small for that, or some sort or whacky stack pointer stunts > that lead to valgrind thinking it's part of the stack. > That's interesting. The block in question is not a thread stack but a regular struct. However, at other places the code does play with manually-allocated thread stacks, hence stack pointer switches that might confuse Valgrind. Can you see a way to confirm this conjecture? In other words, how can I ensure this is a legitimate false positive? Many thanks, -- Paul-Antoine Arras |
|
From: Tom H. <to...@co...> - 2020-01-14 19:22:09
|
On 14/01/2020 19:15, Paul-Antoine Arras wrote: > Le 14/01/2020 à 20:01, Tom Hughes a écrit : > >> Using it as a thread stack could also do it, though it looks a >> bit small for that, or some sort or whacky stack pointer stunts >> that lead to valgrind thinking it's part of the stack. > > That's interesting. The block in question is not a thread stack but a > regular struct. However, at other places the code does play with > manually-allocated thread stacks, hence stack pointer switches that > might confuse Valgrind. > > Can you see a way to confirm this conjecture? In other words, how can I > ensure this is a legitimate false positive? I wouldn't expect it to go wrong with straightforward use where malloced blocks are passed to clone as a thread stack, at least if the correct size is passed, but if you start doing some sort of coroutines or green thread type stuff and doing context switching in user space then that's another story. Basically when valgrind thinks the stack pointer is moving upwards on return from a function it will mark the memory between the old and new pointers as invalid, but the problem is that there's no way to be sure from a write to the stack pointer if that is it being increased/decreased or if it's a switch to a new stack so valgrind has to employ heuristics and assume that big changes (for some value of big) are switches and small changes are moving up/down the stack. Tom -- Tom Hughes (to...@co...) http://compton.nu/ |