C/C++ 프로그램이 main()보다 먼저 크래시 할 수 있는 방법이 있습니까?
프로그램이 main()보다 먼저 크래시 할 수 있는 방법이 있습니까?
gcc를 사용하면 함수에 생성자 속성을 태그할 수 있습니다(이것에 의해 함수가 먼저 실행됨).main
에서 )는 다음과 같습니다.premain
으로 불러주세요.main
:
#include <stdio.h>
void premain() __attribute__ ((constructor));
void premain()
{
fputs("premain\n", stdout);
}
int main()
{
fputs("main\n", stdout);
return 0;
}
premain
하다 보면 됩니다.main
.
나도 같은 문제에 직면했었다.★★★★★★★★★★★★★★★★★★★★★★★★메인 프로세스에서 너무 많은 로컬 변수(대규모 배열)가 초기화되어 로컬 변수 크기가 1.5MB의
이로 인해 스택 포인터가 상당히 크고 OS가 이 점프를 무효로 검출하여 악성일 가능성이 있는 프로그램을 크래시합니다.
버버디
합니다. GDB g g기
합니다.
3. 분해
. %합니다. 0xGGGGGGG입니다.%parames(%pause)
이 GGGG 값이 너무 높으면 나와 같은 문제가 발생합니다.
메인에서 모든 로컬 변수의 총 크기를 확인합니다.
간단한 대답은 "그렇다"입니다.
더 구체적으로 말하면, 우리는 이것에 대한 두 가지 원인을 구별할 수 있습니다.이를 구현 의존형 및 구현 의존형이라고 합니다.
사용 환경에 전혀 의존하지 않는 한 가지 사례는 여기서 설명한 C++의 정적 객체입니다.다음 코드가 삭제되기 전에main()
:
#include <iostream>
class Useless {
public:
Useless() { throw "You can't construct me!"; }
};
static Useless object;
int main() {
std::cout << "This will never be printed" << std::endl;
return 0;
}
플랫폼에 의존한 원인이 더 흥미롭습니다.여기에도 몇 가지 언급이 있었습니다.여기서 몇 번 언급한 것 중 하나는 동적으로 링크된 라이브러리(Windows의 경우 DLL, Linux의 경우 SO 등)의 사용입니다.OS의 로더에 의해 라이브러리가 로딩되는 경우입니다.main()
어플리케이션이 종료되기 전에 종료되는 경우가 있습니다.main()
.
이 원인의 보다 일반적인 버전은 입력점을 호출하기 전에 바이너리 입력점이 수행하는 모든 작업에 대해 말하는 것입니다.main()
바이너리를 때매우 블록이 생성되면 이이 당신의 바이너리를 합니다.main()
이 코드에서는 C/C++ 표준 라이브러리를 초기화합니다.이 코드는 몇 가지 이유로 실패할 수 있습니다(1가지에 할당하려고 하는 모든 종류의 시스템리소스가 부족).
가 코드 전에 코드를 중 main()
는 TLS 콜백을 사용하고 있습니다(구글에서 자세한 내용을 알려드립니다).이 기술은 일반적으로 말웨어에서 기본 디버깅 방지 기술로 볼 수 있습니다(이 트릭은 당시 olydbg를 속이는 데 사용되었지만 여전히 그럴지는 알 수 없습니다).
은, 는, 「하면, 가 「이진수의 될 수 하는 입니다.main()
그 답은 지옥이야, 그래!
메인 전에 로드되는 공유 객체(DLL)에 의존하는 프로그램은 메인 전에 실패할 수 있습니다.
다이내믹 링커 라이브러리의 Linux 코드(ld-*.so)에서는 메인보다 훨씬 전에 라이브러리의 종속성을 제공하기 위해 실행됩니다.필요한 라이브러리를 찾을 수 없거나, 라이브러리에 액세스할 수 없는 권한이 있거나, 일반 파일이 아니거나, 프로그램을 링크한 동적 링커가 프로그램을 링크할 때 가져야 한다고 생각했던 기호가 없는 경우 오류가 발생할 수 있습니다.
또한 각 라이브러리가 링크되면 일부 코드가 실행됩니다.이는 라이브러리가 더 많은 라이브러리를 링크해야 하거나 일부 컨스트럭터를 실행해야 하기 때문입니다(C 프로그램에서도 라이브러리는 일부 C++ 또는 컨스트럭터를 사용하는 다른 것을 가질 수 있습니다).또한 표준 C 프로그램에서는 stdio FILEs stdin, stdout 및 stderr이 이미 생성되어 있습니다.많은 시스템에서 이러한 시스템은 닫힐 수도 있습니다.이는 이들(및 그 버퍼)이 malloc()ed였음을 의미하며 이는 실패할 수 있음을 의미합니다.또, 이러한 FILE 구조가 나타내는 파일 기술자에 대해서, 그 외의 조작을 실시했을 가능성이 있기 때문에, 장해가 발생할 가능성이 있습니다.
OS가 프로그램에 전달된 환경변수 및/또는 명령줄 인수를 설정하는 데 실패했을 경우 발생할 수 있는 다른 문제들도 있습니다.main을 호출하기 전에 main 이전 코드가 이 데이터로 인해 발생한 것 같습니다.
본방송 전에 많은 일들이 일어납니다.그들 중 누구라도 치명적인 방법으로 실패할 수 있다.
「 」 、 「 Windows 」 。이 DLL을 DLL보다 먼저 할 수 .main()
기동합니다.그DllMain
는 DLL보다 먼저 됩니다.main()
에러가 발생했을 경우, 프로세스 전체가 정지하거나 크래쉬 할 가능성이 있습니다.
확실하지 않지만 다음과 같은 글로벌 변수가 있는 경우:
static SomeClass object;
int main(){
return 0;
}
메인 실행 전에 'SomeClass' 생성자가 프로그램을 크래시할 수 있습니다.
여러 가지 가능성이 있습니다.
먼저 메인 실행 전에 실제로 무슨 일이 일어나는지 파악해야 합니다.
- 동적 라이브러리의 부하
- 글로벌 초기화
- 일부 컴파일러에서는 일부 함수를 명시적으로 실행할 수 있습니다.
이것들 중 어느 것이든, 몇개의 방법으로 크래시의 원인이 됩니다.
- 통상적인 정의되지 않은 동작(회의용 늘 포인터, 접근하지 말아야 할 메모리에 대한 액세스...)
- > > > > > > > an an an an an an an an an an an an an an an there an there an there there since 때문에 발생하는입니다.
catch
,terminate
호출되고 이 종료됩니다.
디버깅이 수 은 삼가야 .따라서 코드를 실행하지 않는 것이 좋습니다.main
한 를 선호하거나, 느긋한 초기화를 선호하거나, 또는 '느긋한 초기화' 또는 '느긋한 초기화' 내에서 합니다.main
.
물론 DLL에 장애가 발생하여 수정할 수 없는 경우에는 매우 곤란한 상황에 처하게 됩니다.
C++ 프로그램이 있는 경우 메인이 입력되기 전에 함수 및 생성자를 통해 변수와 개체를 초기화할 수 있습니다.이들 중 하나의 버그로 인해 프로그램이 크래쉬할 수 있습니다.
확실히 c++로, 컨스트럭터가 있는 정적 객체는 메인보다 먼저 호출됩니다.그것들은 죽을 수 있습니다.
c에 대해 확실하지 않다
여기 샘플이 있습니다.
class X
{
public:
X()
{
char *x = 0;
*x = 1;
}
};
X x;
int main()
{
return 0;
}
메인보다 먼저 크래시됩니다.
종류: http://blog.ksplice.com/2010/03/libc-free-world/
표준 라이브러리를 사용하지 않고 컴파일할 경우 다음과 같습니다.gcc - nostdlib - o hello . c
main()을 실행하는 방법을 모르기 때문에 크래시됩니다.
C++ 프로그램의 글로벌오브젝트와 스태틱오브젝트는 main()의 첫 번째 문이 실행되기 전에 컨스트럭터를 호출하기 때문에 컨스트럭터 중 하나의 버그로 인해 크래시가 발생할 수 있습니다.
하지만 C 프로그램에서는 이 문제가 발생할 수 없습니다.
의 의미에 , ' 중 실행되기 할 수 하고, 이의 크기가 스택스페이스를 하면, 「Main」이라고이 적절합니다.지 예를 생각할 수 있습니다.대형 배열을 로컬 변수로 선언하고 이 배열의 크기가 사용 가능한 스택 공간을 초과하면 다음과 같은 예를 얻을 수 있습니다.stack overflow
코드의 첫 번째 줄이 실행되기 전에 main으로 입력합니다.
예를 들면, 다음과 같습니다.
int a = 1;
int b = 0;
int c = a / b;
int main()
{
return 0;
}
당신이 이런 일을 할 것 같지는 않지만, 만약 당신이 많은 매크로 매직을 한다면, 그것은 완전히 가능합니다.
class Crash
{
public:
Crash( int* p )
{ *p = 0; }
};
static Crash static_crash( 0 );
void main()
{
}
물론입니다. 운영체제나 런타임 코드에 버그가 있으면.C++는 특히 이 동작으로 악명이 높지만 C에서도 발생할 수 있습니다.
플랫폼/libc에 대해서는 아직 언급하지 않았습니다.이 있다.main()
셋업과 는 모든 무효가 이것은 합니다.)- 랫랫- 。 - 잘잘잘잘잘잘잘잘잘잘잘잘잘잘잘잘잘잘잘잘( 。 - 잘잘잘잘잘잘(((((( ( OS ) 。
는 (ACE와 C++ C 는 이와할 수 "main을 덮어쓰고 (메인)을 지정합니다. 주요하다int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
정보를 를 일반 합니다.int argc, char* argv[]
후, 의 「통상의」를 합니다.int main(int argc, char* argv[])
물론 이러한 라이브러리가 이를 올바르게 구현하지 않으면(아마도 잘못된 형식의 명령줄 arg의 원인) 크래시가 발생할 수 있습니다.
이 에게는, 하기 전에 추락한 것처럼 보일 .main
을 전에 크래시하는 한 예main
stackoverflow의 경우:
int main() {
char volatile stackoverflow[1000000000] = {0};
return 0;
}
언급URL : https://stackoverflow.com/questions/2518415/is-there-any-way-a-c-c-program-can-crash-before-main
'sourcecode' 카테고리의 다른 글
속성을 지정합니다.단일 파일 구성 요소 vue js에 $el이 정의되지 않았습니다. (0) | 2022.07.23 |
---|---|
Http용 헤더 추가URL 접속 (0) | 2022.07.23 |
Nuxtjs가 비동기 데이터 내에서 Firestore 데이터를 가져옵니다. (0) | 2022.07.23 |
main()은 C와 C++에서 무엇을 반환해야 합니까? (0) | 2022.07.23 |
Linux __user 매크로의 의미는 무엇입니까? (0) | 2022.07.23 |