컴파일 시 스택 사용량 확인
C에서 컴파일 시간에 함수가 필요로 하는 스택 크기를 알고 출력할 수 있는 방법이 있습니까? 여기 제가 알고 싶은 것은 다음과 같습니다.
몇 가지 기능을 사용해 보겠습니다.
void foo(int a) {
char c[5];
char * s;
//do something
return;
}
이 함수를 컴파일할 때 호출할 때 스택 공간을 얼마나 소모하는지 알고 싶습니다.이것은 큰 버퍼를 숨기는 구조의 온스택 선언을 탐지하는 데 유용할 수 있습니다.
다음과 같은 것을 인쇄할 수 있는 것을 찾고 있습니다.
: 은 file fo.c : function fo stack n
바이트들
생성된 어셈블리를 보지 않고 그것을 알 수 있는 방법이 있습니까? 또는 컴파일러에 대해 설정할 수 있는 제한이 있습니까?
업데이트 : 주어진 프로세스에 대해 런타임 스택 오버플로를 방지하려는 것이 아니라 컴파일러가 결정한 함수 스택 사용이 컴파일 프로세스의 출력으로 사용 가능한 경우 런타임 전에 찾을 수 있는 방법을 찾고 있습니다.
다른 말로 하자면, 함수에 로컬인 모든 객체의 크기를 알 수 있을까요? 컴파일러 최적화는 내 친구가 아닐 것입니다. 왜냐하면 몇몇 변수는 사라지지만 상한은 괜찮기 때문입니다.
리눅스 커널 코드는 x86의 4K 스택에서 실행됩니다.그래서 그들은 신경을 씁니다.이를 확인하기 위해 사용하는 것은 자신들이 작성한 펄 스크립트이며, 최근 커널 타르볼(2.6.25가 이를 가지고 있음)에서 스크립트/checkstack.pl 로 찾을 수 있습니다.objdump의 출력으로 실행되며 사용 설명서는 첫 번째 주석에 있습니다.
사용자 공간 바이너리에 이미 오래전에 사용했던 것 같은데 펄 프로그래밍을 조금만 알고 계시면 고장나면 고치기 쉽습니다.
어쨌든 기본적으로 GCC의 산출물을 자동으로 보는 것입니다.그리고 커널 해커들이 그런 툴을 작성했다는 것은 GCC로 그것을 할 수 있는 정적인 방법이 없다는 것을 의미합니다(혹은 그것이 아주 최근에 추가되었을 수도 있지만, 나는 그렇게 생각하지 않습니다).
그건 그렇고, mingw 프로젝트의 objdump와 ActivePerl, 또는 Cygwin을 사용하면 윈도우와 다른 컴파일러로 얻은 바이너리에서도 그렇게 할 수 있을 것입니다.
StackAnyser는 실행 코드 자체와 디버깅 정보를 조사하는 것 같습니다.이 답변에 의해 설명된 것은 제가 찾고 있는 것입니다. 스택 분석기는 저에게 오버킬로 보입니다.
ADA를 위해 존재하는 것과 유사한 것이 좋습니다.gnat 매뉴얼의 이 매뉴얼 페이지를 보십시오.
22.2 정적 스택 사용량 분석
-fstack-usage로 컴파일된 장치는 기능별로 사용된 스택의 최대 양을 지정하는 추가 파일을 생성합니다.파일의 기본 이름은 .su 확장자가 있는 대상 개체 파일과 동일합니다.이 파일의 각 줄은 세 개의 필드로 구성됩니다.
* The name of the function.
* A number of bytes.
* One or more qualifiers: static, dynamic, bounded.
두 번째 필드는 함수 프레임의 알려진 부분의 크기에 해당합니다.
한정자 정적은 함수 프레임 크기가 순수하게 정적임을 의미합니다.이는 일반적으로 모든 지역 변수가 정적 크기를 가짐을 의미합니다.이 경우 두 번째 필드는 함수 스택 활용도의 신뢰할 수 있는 척도입니다.
한정자 동적은 함수 프레임 크기가 정적이 아님을 의미합니다.이는 주로 일부 지역 변수가 동적 크기를 가질 때 발생합니다.이 한정자가 단독으로 나타나는 경우 두 번째 필드는 함수 스택 분석의 신뢰할 만한 측도가 아닙니다.제한된 필드로 자격을 갖추면 두 번째 필드가 함수 스택 활용도의 신뢰할 수 있는 최대치임을 의미합니다.
정적 코드 분석이 이에 대한 충분한 수치를 제공하지 못하는 이유를 모르겠습니다.
임의의 주어진 함수에서 모든 지역 변수를 찾는 것은 사소한 일이며, 각 변수에 대한 크기는 C 표준(빌트 인 유형의 경우) 또는 계산(구조 및 조합과 같은 복잡한 유형의 경우)을 통해 구할 수 있습니다.
물론, 컴파일러는 패딩, 레지스터에 변수를 넣거나 불필요한 변수를 완전히 제거하는 등 다양한 최적화 작업을 수행할 수 있기 때문에 100% 정확하다고 보장할 수는 없습니다.그러나 그것이 주는 어떤 대답이라도 최소한 좋은 추정이 되어야 합니다.
구글 검색을 빠르게 해서 StackAnalyzer를 찾았는데 다른 static code 분석 도구들도 비슷한 기능을 가지고 있는 것 같습니다.
만약 당신이 100% 정확한 수치를 원한다면, 당신은 컴파일러의 출력을 보거나 Ralph가 그의 답장에서 제안한 것처럼 실행시간 동안 그것을 확인해야 할 것입니다.
당신의 모든 것을 정리하는 사람이기 때문에 컴파일러만이 정말로 알 것입니다.생성된 어셈블리를 보고 프리앰블에 얼마나 많은 공간이 예약되어 있는지 확인해야 할 것입니다. 그러나 그것은 실제로 다음과 같은 것들을 설명하지 않습니다.alloca
그들은 실행시간에 그들의 일을 합니다.
여러분이 임베디드 플랫폼에 있다고 가정할 때, 여러분은 툴체인이 이것을 시도하고 있다는 것을 발견할 수 있을 것입니다.우수한 상용 임베디드 컴파일러(예: Arm/Keil 컴파일러)는 스택 사용에 대한 보고서를 생성하는 경우가 많습니다.
물론 인터럽트와 재귀는 일반적으로 그 범위를 약간 넘어선 것이지만, 어떤 사람이 스택 어딘가에 있는 수 메가바이트의 버퍼를 가지고 심각한 실수를 저질렀는지 대략적으로 알 수 있습니다.
정확히 "컴파일 시간"은 아니지만, 빌드 후 단계로 수행합니다.
- 링커가 당신을 위해 지도 파일을 만들도록 합니다.
- 지도 파일의 각 기능에 대해 실행 파일의 해당 부분을 읽고 기능 프롤로그를 분석합니다.
Stack Analyzer와 비슷하지만 훨씬 간단합니다.나는 실행 파일이나 해체를 분석하는 것이 컴파일러 출력을 얻을 수 있는 가장 쉬운 방법이라고 생각합니다.컴파일러가 내부적으로 알고 있기는 하지만 이를 통해 얻을 수 없을 것 같습니다(컴파일러 벤더에게 기능 구현을 요청하거나 오픈 소스 컴파일러를 사용하는 경우 직접 수행하거나 누군가가 대신 수행하도록 요청할 수도 있습니다).
이를 구현하려면 다음 작업이 필요합니다.
- 지도 파일을 파싱할 수 있는
- 실행 파일 형식 이해
- 기능 프롤로그가 어떤 모습인지 알고 그것을 "decode"할 수 있습니다.
목표 플랫폼에 따라 이 작업이 얼마나 쉽거나 어려울지가 달라집니다. (내장되어 있습니까?어떤 CPU 아키텍처?무슨 컴파일러?)
이 모든 작업은 x86/Win32에서 수행할 수 있습니다. 하지만 이런 작업을 전혀 수행하지 않고 처음부터 이 모든 작업을 수행해야 한다면 작업이 완료되고 작업이 완료되기까지 며칠이 걸릴 수 있습니다.
일반적으로 그렇지 않습니다.이론 컴퓨터 과학의 문제 중지는 일반 프로그램이 주어진 입력에 대해 중단되는지 여부를 예측할 수조차 없다는 것을 암시합니다.일반적으로 프로그램 실행에 사용되는 스택을 계산하는 것은 훨씬 더 복잡할 것입니다.그래서 안 돼요.아마 특별한 경우일 겁니다.
임의 길이의 입력에 따라 재귀 수준이 달라지며 이미 운이 없다고 가정해 보겠습니다.
언급URL : https://stackoverflow.com/questions/126036/checking-stack-usage-at-compile-time
'programing' 카테고리의 다른 글
editline/history.h 및 editline/readline.h를 찾을 수 없음/이미 설치된 개발자 도구로 컴파일하려고 할 때 macOS에서 작동함 (0) | 2023.10.27 |
---|---|
더 작은 배당과 더 큰 분배의 모듈러스는 어떻게 작동합니까? (0) | 2023.10.27 |
window cmd를 사용하여 사용자 권한을 보는 방법? (0) | 2023.10.27 |
jQuery에서 마우스 휠 이벤트를 얻습니까? (0) | 2023.10.27 |
Spring 보안에서 하나를 제외한 모든 URL 허용 (0) | 2023.10.27 |