GCC 4.7.2를 사용하고 있습니다.개발 도구 세트CentOS 5의 패키지(CentOS 5는 이전 Linux 버전과의 호환성이 필요하고 GCC 4.7은 4.4보다 최적화되어 있기 때문에).
내 바이너리가 RHEL4에서 실행되는 것을 방지하는 기호가 있습니다: __stack_chk_fail@GLIBC_2.4
. 일부 C++ 프로그램에만 포함되어 있으며 이 -fno-stack-protector
플래그는 도움이 되지 않습니다.
다음은 문제를 재현하기 위한 최소 프로그램입니다(그러나 동일한 stdio.h
방법을 사용함).
#include <iostream>
int main(int argc, char *argv[]) {
for(int i=0; i < argc; i++)
std::cout << " " << argv[i];
return 0;
}
최적화( -O
/ )로 -O2
컴파일할 때 인용됩니다 __stack_chk_fail
.
$ g++ -fno-stack-protector -O2 foo.cc
$ readelf -s a.out | grep chk
15: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@GLIBC_2.4 (5)
105: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@@GLIBC_2
이 기호가 여기에 나타나는 이유와 이를 제거하는 방법을 아시나요?
만일을 대비해 전체 readelf
출력은 다음과 gcc -v
같습니다 .여기.
편집: 이 문제는 Red Hat Developer Toolset 1.1에만 해당될 수 있습니다. 기본 CentOS 컴파일러 __stack_chk_fail
는 참조되지 않습니다.
답변1
이 기호는 에서 유래되었습니다 libstdc++_nonshared.a
.
배포판의 GCC와 달리 devtoolset의 GCC에는 libstdc++의 공유되지 않는 부분이 있습니다. GCC 4.7의 libstdc++.so는 GCC 4.1의 libstdc++와 정적으로 연결된 추가 함수를 사용하는 링커 스크립트입니다.
$ cat /opt/centos/devtoolset-1.1/root/usr/lib/gcc/i386-CentOS-linux/4.7.2/libstdc++.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
INPUT ( /usr/lib/libstdc++.so.6 -lstdc++_nonshared )
스택 보호기를 비활성화한 상태에서 다시 컴파일한 후 libstdc++_nonshared.a
최종 프로그램은 RHEL4에서 작동합니다.
답변2
GLibC와 함께 제공됩니다. 이전 GLibC에 대해 빌드합니다.
GCC 4.7에 최적화된 어셈블리 코드를 생성한 다음 이를 이전 시스템에서 어셈블하고 링크하도록 지시할 수 있습니다.