GCC compiles without optimization parameters, previously used to be-o pits.
#include <stdio.h> #include <string.h> int main () {char url[512]; sprintf (URL, "218.26.242.56/0/0/1023/6d6168bf1a7294ae0e1c071171adcd48.mp4"); printf ("%s\n", url); char*p = URL; strcpy (p+15,p+22); printf ("%s\n", url); return 0;}
The printing results should be as follows
218.26.242.56/0/0/1023/6d6168bf1a7294ae0e1c071171adcd48.mp4
218.26.242.56/06d6168bf1a7294ae0e1c071171adcd48.mp4
but under the centos6.3 system,gcc4.4.7,
The print result will be
218.26.242.56/0/0/1023/6d6168bf1a7294ae0e1c071171adcd48.mp4
218.26.242.56/0/f1a7294a1a7294ae0e1c071171adcd48.mp4
at present , the experiment redhat5.05.7,centos7.2 system will not have problems, only 6.x (try 6.0, 6.3, 6.7) gcc4.4.7 will have problems
Download 4.4.7 Source code
wget http://ftp.gnu.org/gnu/gcc/gcc-4.4.7/gcc-4.4.7.tar.bz2
The code is as follows
extern void abort (void); extern int inside_main; Char *strcpy (char *d, const char *s) {char *r = D; #if defined __optimize__ &&!defined __optimize_size__ if (INS Ide_main) Abort (), #endif while ((*d++ = *s++)); return r;}
Theoretically, this shouldn't be the case.
centos6.x 's strcpy source code for sinks
char *strcpy (CHAR&NBSP;*DEST,&NBSP;CONST&NBSP;CHAR&NBSP;*SRC) { return __kernel_strcpy (DEST,&NBSP;SRC);} static inline char *__kernel_strcpy (CHAR*DEST,&NBSP;CONST&NBSP;CHAR&NBSP;*SRC) { char *xdest = dest; asm volatile ("\ n" "1: move.b (% 1) +, (%0) +\n " "&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;JNE&NBSP;&NBSP;&NBSP;&NBSP;1B" : "+a" ( dest), "+a" (SRC) : : "Memory"); return xdest;}
There is also no problem.
Modify the system function to a custom function, using the same code, and the results are correct.
Another optimized version of the strcpy code has been found on the network, using the Register acceleration effect, and the so-called GCC optimization code found on the web is similar
char * strcpy (DEST,&NBSP;SRC) char *dest; const char *src; { register char c; char *__unbounded s = (char *__ unbounded) CHECK_BOUNDS_LOW (SRC); const ptrdiff_t off = check_bounds_low (dest) - s - 1; size_t n; do { c = *s++; s[off] = c; } while (c != '); n = s - src; (void) CHECK_BOUNDS_HIGH (src &NBSP;+&NBSP;N); (void) CHECK_BOUNDS_HIGH (dest + n); return dest; }
It is not a problem to use it as a custom function.
Continue to discover that strncpy and sprintf also encounter the same problem.
With memcpy, there's no problem.
memcpy (P+11,p+18,strlen (p+18) +1);
Look at the source, and strcpy is no different
void *memcpy (void *dest, const void *SRC, size_t len) {char *d = dest; const char *s = SRC; while (len--) *d++ = *s++; return dest;}
Temporarily do not understand why strcpy, strncpy, sprintf under the gcc4.4.7, self-movement will cause problems.
Previously seen on the Internet strcpy optimization function, in 64-bit systems, with eight-byte long shaping to replicate, but not seen in the library, just as the optimization of custom code recommendations.
In this example, if we change the p+15 to p+16, everything is normal and the total length of the string is reduced to p+32 (that is, * (p+32) =0), then everything is fine. The error field length is 8 bytes, which is related to 8, where the system is suspected to be optimized, but it is unclear who is optimizing and what the optimized code looks like.
Therefore, it is recommended that if you want to move the string itself, do not use the MEM function using str.
--------------------
Colleagues provide a post that says memory overlap issues
http://blog.csdn.net/stpeace/article/details/39456645
But the author of this example doesn't actually analyze the idea.
Char str []= "123456789"; strcpy (str + 2, str);
itself in the code logic is wrong, from the source can be seen from the previous copy, will lead to the memory behind the overwrite. And this is not a situation that we met this time.
According to the source code should result is 1212121212121212 ... Until the cross-border crash.
But the actual result is 121234565678.
Tried it on a couple of machines.
On the gcc4.1.1, it is 12121212121 ... Collapse
Gcc4.4.7 Display 121234565678
gcc4.8.5 Display 12123456789
There should be optimizations on 4.4.7, but 4.8.5 should be solved, and even this logical anomaly is supported.
Found on the Internet gcc4.7 on the strcpy of the compilation bug, why is not also related.
-----------------
After checking the internet and finding it misleading, we should study Libc.so's code instead of the GCC code.
See the next libc source, define a lot of implementation, in different devices using different optimized sink code, should be using 8 bytes copy instead of a single string copy, in libc2.12 have bug,libc2.17 should be resolved.
View their strcpy code
libc2.12.1 on
/* Copy SRC to DEST. */char *strcpy (dest, SRC) char *dest; const char *SRC; {Reg_char C; Char *__unbounded s = (char *__unbounded) check_bounds_low (SRC); Const ptrdiff_t off = Check_bounds_low (dest)-s-1; size_t N; do {c = *s++; S[off] = c; } while (c! = ') '; n = s-src; (void) Check_bounds_high (src + N); (void) Check_bounds_high (dest + N); return dest;}
libc2.17 on
/* Copy SRC to DEST. */char *strcpy (dest, SRC) char *dest; const char *SRC; {char C; Char *__unbounded s = (char *__unbounded) check_bounds_low (SRC); Const ptrdiff_t off = Check_bounds_low (dest)-s-1; size_t N; do {c = *s++; S[off] = c; } while (c! = ') '; n = s-src; (void) Check_bounds_high (src + N); (void) Check_bounds_high (dest + N); return dest;}
Found 2.17 compared to 2.12 no change, is to cancel the register (Reg_char into char), in this blog said the importance of register, can improve the copy speed, do not understand why 2.17 canceled the register.
http://blog.csdn.net/astrotycoon/article/details/8114786
Continue testing
Found on the libc2.12
(GDB) bt#0 0x00000036a7532664 in __strcpy_ssse3 () from/lib64/libc.so.6#1 0x0000000000400671 in Main () at test.c:32
The real use is the strcpy under the SSSE3 instruction set. s implementation
Under the glib2.17
(GDB) bt#0 __strcpy_sse2_unaligned () at: /sysdeps/x86_64/multiarch/strcpy-sse2-unaligned. S:232#1 0x0000000000400655 in Main () at Test.c:9
directly into the. S-sink code, even libc.so are not entered, but this assembly function strcpy-sse2-unaligned is also glib inside
The assembly is really powerless and completely impossible.
However, it seems that the so-called C source for analysis is not much help also easy to cause misunderstanding, because the bottom of the library at all without the C program source AH.
This article is from "Flying Justice Blog" blog, please be sure to keep this source http://xzq2000.blog.51cto.com/2487359/1915623
strcpy will have bugs on the centos6.x,gcc4.4.7 version, and self-moving results in overwriting errors overlap