0
votes

I'm relatively new at debugging valgrind errors, and this one has me stumped:

==1920== Invalid write of size 1
==1920==    at 0x4C2ECC7: strcpy (/builddir/build/BUILD/valgrind-3.11.0/memcheck/../shared/vg_replace_strmem.c:506)
==1920==    by 0x1D533B57: CSR_bullet (packages/tests-vg/vetr/src/cstringr.c:448)
            ... redacted (see end for full error)
==1920==  Address 0x1bd1be1f is 5,599 bytes inside a block of size 7,960 alloc'd
==1920==    at 0x4C2BBAD: malloc (/builddir/build/BUILD/valgrind-3.11.0/coregrind/m_replacemalloc/vg_replace_malloc.c:299)
==1920==    by 0x4F3D3E: GetNewPage (svn/R-devel/src/main/memory.c:879)
            ... redacted (see end for full error)

Notice this is 1 byte well inside an alloc'd block. I've seen similar errors that involve writing after, or before, or into a free'd block, or even writes where the write size is greater than end of block - address (therefore overflowing), but I can't find one like this one.

This is happening on the R CRAN check farm at this line of code.

I cannot reproduce the error locally with valgrind on OSX or on a linux VM.

Beyond that, the error doesn't make sense to me. Why can't I write 1 byte in the middle of the allocated block? This is all running inside R, so it's possible I guess that the allocation in question was made by a different part of the program and it is somehow reserved (one possible hint that that's happening is that the allocations I requested from R were less than 60 bytes when the error shows up), but I don't know if that is something that valgrind would be able to detect anyway.

Full error:

==1920== Invalid write of size 1
==1920==    at 0x4C2ECC7: strcpy (/builddir/build/BUILD/valgrind-3.11.0/memcheck/../shared/vg_replace_strmem.c:506)
==1920==    by 0x1D533B57: CSR_bullet (packages/tests-vg/vetr/src/cstringr.c:448)
==1920==    by 0x1D53317D: CSR_bullet_ext (packages/tests-vg/vetr/src/cstringr-ext.c:107)
==1920==    by 0x4852BD: do_dotcall (svn/R-devel/src/main/dotcode.c:1252)
==1920==    by 0x4C274D: Rf_eval (svn/R-devel/src/main/eval.c:728)
==1920==    by 0x4C3AB5: R_execClosure (svn/R-devel/src/main/eval.c:1617)
==1920==    by 0x4C2391: Rf_eval (svn/R-devel/src/main/eval.c:747)
==1920==    by 0x4C29E0: forcePromise (svn/R-devel/src/main/eval.c:520)
==1920==    by 0x4C27A1: Rf_eval (svn/R-devel/src/main/eval.c:647)
==1920==    by 0x4C7746: do_withVisible (svn/R-devel/src/main/eval.c:2998)
==1920==    by 0x4F7104: do_internal (svn/R-devel/src/main/names.c:1363)
==1920==    by 0x4B553B: bcEval (svn/R-devel/src/main/eval.c:6503)
==1920==  Address 0x1bd1be1f is 5,599 bytes inside a block of size 7,960 alloc'd
==1920==    at 0x4C2BBAD: malloc (/builddir/build/BUILD/valgrind-3.11.0/coregrind/m_replacemalloc/vg_replace_malloc.c:299)
==1920==    by 0x4F3D3E: GetNewPage (svn/R-devel/src/main/memory.c:879)
==1920==    by 0x4F5814: Rf_allocVector3 (svn/R-devel/src/main/memory.c:2659)
==1920==    by 0x4CAEAF: Rf_allocVector (svn/R-devel/src/include/Rinlinedfuns.h:247)
==1920==    by 0x4CAEAF: do_growconst (svn/R-devel/src/main/eval.c:7490)
==1920==    by 0x4B64BD: bcEval (svn/R-devel/src/main/eval.c:6483)
==1920==    by 0x4C2207: Rf_eval (svn/R-devel/src/main/eval.c:624)
==1920==    by 0x4C3AB5: R_execClosure (svn/R-devel/src/main/eval.c:1617)
==1920==    by 0x4BAE13: bcEval (svn/R-devel/src/main/eval.c:6454)
==1920==    by 0x4C2207: Rf_eval (svn/R-devel/src/main/eval.c:624)
==1920==    by 0x4C3AB5: R_execClosure (svn/R-devel/src/main/eval.c:1617)
==1920==    by 0x4BAE13: bcEval (svn/R-devel/src/main/eval.c:6454)
==1920==    by 0x4C2207: Rf_eval (svn/R-devel/src/main/eval.c:624)
1
there is probably a continuation of the message which tells when the block was deleted/freed. - Serge
Wouldn't it then say "... of size 7,960 free'd"? The word "free" does not appear in the full output I link. - BrodieG
Maybe a (uncaught) previous error has overwritten a memory-control-block? - wildplasser
... && *(string_copy + 1)) why do you suppress the final '\n' in the count of newlines? (besides the strange syntax: ... && string_copy[1]) is more common, IMHO ) - wildplasser
size_t i = 0; i < newlines; ++i) size_all = CSR_add_szt(size_all, ctd_size); You are performing multiplication by repetitive addition here. Are you afraid that a size_t overflows? - wildplasser

1 Answers

1
votes

Such error can happen when using memory pools.

Typically, a lib or an application (such as R) can build its own allocator by getting big blocks e.g. from malloc, and then allocating small blocks from these big blocks. Valgrind has some client requests allowing to describe these blocks (big or inner smaller blocks), and their allocations.

With such client requests, you might have a part of a malloc allocated block that is in fact marked as not addressable.

Seeing the stack trace entry :

==1920== by 0x4F3D3E: GetNewPage (svn/R-devel/src/main/memory.c:879)

the above explanation looks plausible.

This then might be an indication that there is a real bug somewhere in R and/or in the way the R allocator describes its memory pool to valgrind