GCC 컴파일 - __stack_chk_fail@GLIBC_2.4 기호는 어디에서 왔습니까?

GCC 컴파일 - __stack_chk_fail@GLIBC_2.4 기호는 어디에서 왔습니까?

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에 최적화된 어셈블리 코드를 생성한 다음 이를 이전 시스템에서 어셈블하고 링크하도록 지시할 수 있습니다.

관련 정보