Bug 148543 - memcpy(x, x, n) is OK
Summary: memcpy(x, x, n) is OK
Status: RESOLVED WORKSFORME
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: 3.2.3
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-05 20:49 UTC by John Reiser
Modified: 2023-12-15 06:54 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Reiser 2007-08-05 20:49:28 UTC
Nothing can go wrong when the source and destination to memcpy() are identical,
yet memcheck 3.2.3 still complains:

==3031== Source and destination overlap in memcpy(0x4077E00, 0x4077E00, 4)
==3031==    at 0x4006A3A: memcpy (mc_replace_strmem.c:116)
==3031==    by 0x1D952D: (within /usr/X11R6/lib/libXt.so.6.0)
==3031==    by 0x1DA486: _XtGetResources (in /usr/X11R6/lib/libXt.so.6.0)
==3031==    by 0x1C4F89: (within /usr/X11R6/lib/libXt.so.6.0)
==3031==    by 0x1C582A: _XtCreateWidget (in /usr/X11R6/lib/libXt.so.6.0)
==3031==    by 0x1F1992: (within /usr/X11R6/lib/libXt.so.6.0)
==3031==    by 0x1F1AD4: XtVaCreateManagedWidget (in /usr/X11R6/lib/libXt.so.6.0)
==3031==    by 0x8063DE2: (within /usr/bin/xterm)
==3031==    by 0x544D7E: (below main) (in /lib/libc-2.3.6.so)

This particular case was generated by "valgrind xterm" where xterm is from
xterm-213-1.FC4, and libXt.so is from xorg-x11-libs-6.8.2-37.FC4.49.2.1 , and
"valgrind --version" reports valgrind-3.2.3
.
Comment 1 Jeremy Fitzhardinge 2007-08-06 00:31:35 UTC
John Reiser wrote:
> Nothing can go wrong when the source and destination to memcpy() are identical,
>   


Not true.  memcpy is undefined when source and dest overlap.  For
example, a powerpc implementation might use the dcbz on the destination,
which has the effect of zeroing a cache line, potentially before it has
been read as a source.

    J
Comment 2 John Reiser 2007-08-06 03:47:07 UTC
The Standard does say that any overlap in memcpy() results in Undefined.  Therefore, the original complaint may be dismissed as "Not a bug."  However, I could amend the complaint with the qualification "on my machine" [not a PowerpC] or "for lengths much less than a cacheline" [in this case, for length 4.]  Then we could discuss particular aspects of portability.  

Another applicable Standard says that (0 + x) is Undefined whenever x is Uninitialized, yet memcheck complains only if memcheck believes that the result affects visible state.  To memcheck, some violations of relevant Standard are ignored, and others are not.  Trying to understand (or even enumerate) the differences confuses to both new and expert users.  The calculus of "What are the implications of a complaint [or no complaint] by memcheck?" becomes muddied by many cases.
Comment 3 Robert Walsh 2007-08-06 04:06:38 UTC
You could say a lot about specific portability issues - for example, a certain uninitialized variable on the stack just happens to be OK all of the time on my machine - but that isn't useful in the general case.  Amongst its many other uses, Valgrind is helping you spot things that may be problems on some machines or in some circumstances even if they work just fine for you on your particular machine.
Comment 4 Tim Ruffing 2021-06-08 18:12:42 UTC
(In reply to Robert Walsh from comment #3)
> You could say a lot about specific portability issues - for example, a
> certain uninitialized variable on the stack just happens to be OK all of the
> time on my machine - but that isn't useful in the general case.  Amongst its
> many other uses, Valgrind is helping you spot things that may be problems on
> some machines or in some circumstances even if they work just fine for you
> on your particular machine.

I agree. But if things work fine, then suppression may be useful. What do you think of adding a way to write a specific suppression that handles exactly that src and dst in a memcpy are identical? Currently it's only possible to write a generic suppression that matches every overlap, or really write suppressions specific for a given program.
Comment 5 Tim Ruffing 2021-06-09 18:58:31 UTC
Sorry for posting again but I forgot to point out that this is a real problem in cases where compilers generate calls to memcpy() even if there's no explicit memcpy() call in the source, e.g., struct assignments.

This happens for both GCC and Clang, see

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=32667
https://bugs.llvm.org/show_bug.cgi?id=11763

Of course it could be "fixed" there but it seems that at least Clang will move in the opposite direction and simply assume from libc that memcpy(x,x,n) is fine.

So I think a suppression in Valgrind or at least a way to write one will be very useful and pragmatic.