linux g++ strcpy overlap 현상을 겪어보신분 계신가요?
글쓴이: iknights / 작성시간: 금, 2014/05/09 - 9:31오전
안녕하세요.
개발 도중 c의 strcpy overlap 현상을 보고 혹시 저와 같은 현상을 겪어보신분이 있는지요?
문제는 동일 소스를 가지고 두개의 동일 환경에 g++ 컴파일 버전만 다른 시스템에서
테스트 결과가 상이 하여 이러한 증상을 겪어보신분이나 해결하신 분의 조언을 얻고자 합니다.
소스: test.cpp
#include <stdio.h> #include <string.h> int main(int argc, char** argv) { char buf[10] = {0,}; char* p = buf; sprintf(buf, " P01=1"); p++; // strcpy overlap 현상 strcpy(buf, p); fprintf(stderr, "%s\n", buf); return 0; } > g++ -o test test.cpp > test
1. A 시스템 (x86_64-redhat-linux)
g++ version 4.1.2
결과: [P01=1]
2. B 시스템 (x86_64-redhat-linux)
g++ version 4.4.7
결과: [P0==1]
strcpy을 memcpy로 고쳐 overlap현상에 대해 정상 처리를 할수 있지만
문제는 이러한 곳이 프로젝트내 한 두군데가 아니다 보니 수정양이 상당할 것으로 보입니다.
이러한 현상을 혹 겪으신 분이나 해결하신분들에 대한 조언을 얻고자 합니다.
감사합니다.
Forums:
strcpy()는 source와
strcpy()는 source와 destination이 overlap되면 안됩니다. (undefined behavior)
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
?
윗 분 말씀대로 저러한 코드 자체가 애초에 strcpy 에서 사용하면 안되는 겁니다.
그리고 현재 이런 문제가 발생하시는 원인은 gcc 버전도 있고, 64비트 타겟이기 때문입니다.
버전에 따라서 저런 문제가 정확히 언제 발생하는지는 확인을 안해봤습니다만 아마도
서로 상이한 버전의 glibc 를 참조하는 경우로 추측됩니다.
즉 플랫폼에 따라서 결과가 상이할 수 있고, 근본적으로 저런 문제가 발생하는 원인은
strcpy 가 단순히 1바이트씩 복사하는 코드가 아니라, xmm 명령으로 최적화되어 생성되기 때문입니다.
어떤 플랫폼에선 그냥 굉장히 단순한 1바이트 복사 코드이지만 어떤 타겟에선 xmm 최적화 코드가 있습니다.
정 코드를 수정하지 않고 꼭 해결해야 한다면 바이너리가 동적 컴파일 되어있다는 가정하에
참조하는 libc 를 슬쩍 변경해도 되지만 이건 사실 전혀 권장하고 싶지 않은 방법입니다.
memcpy도 안됩니다. 메모리 복사할 때 겹쳐도
memcpy도 안됩니다. 메모리 복사할 때 겹쳐도 되는건 memmove가 유일합니다.
하지만 memmove던 memcpy던 일일이 버퍼길이를 구해서 지정해줘야하니까 래퍼 함수를 새로 하나 만드셔서 다 고쳐야겠네요.
아니면 #define으로 strcpy를 래퍼함수로 재정의해주는 방법도 있고요.
어찌되었든 표준라이브러리 건드릴거 아니면 소스는 무조건 고쳐야죠.
댓글 달기