Hide Forgot
Description of problem: Error in strcpy() in 32 bit mode on a 64 bit OS Version-Release number of selected component (if applicable): glibc-2.14.90-19.i686.rpm How reproducible: Always Steps to Reproduce: 1. Execute the simple program below, which shifts left one position a 16 char string. 2. 3. Actual results: A part of the string has been shifted two places Expected results: The full string should be shifted a single place #include <stdio.h> #include <string.h> /* strcpy() must not be inlined */ main() { char dst[30]; char *src = "abcdefghijklmnopq"; /* 17 chars */ strcpy(dst,src); /* plain copy */ strcpy(dst,dst+1); /* shift left one position */ printf("src %s\ndst %s\n",src,dst); return (0); } [linux@dimension emacs]$ ./copy src abcdefghijklmnopq dst bcdefhijklmnopqq This happens in the following sequence, and could be related to some level of harware cache badly shared between the source and destination on the processor used (cpuinfo below). :4AF7B151 660FEFC0 pxor xmm(0),xmm(0) :4AF7B155 F30F6F09 movdqu xmm(1),oword [ecx] :4AF7B159 F30F7F0A movdqu oword [edx],xmm(1) :4AF7B15D 660F7403 pcmpeqb xmm(0),qword [ebx] :4AF7B161 660FD7C0 pmovmskb xmm(0),xmm(0) :4AF7B165 29CB sub ebx,ecx Additional info: [linux@dimension emacs]$ cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 15 model : 75 model name : AMD Athlon(tm) 64 X2 Dual Core Processor 4200+ stepping : 2 cpu MHz : 1000.000 cache size : 512 KB
Calling strcpy that way is invalid. Read e.g. man 3p strcpy: "If copying takes place between objects that overlap, the behavior is undefined." this wording or similar is in ISO C99 as well as POSIX. You need to use memmove for such an overlapping operation.