IT이야기

세그멘테이션 장애란 무엇입니까?

cyworld 2022. 7. 25. 22:31
반응형

세그멘테이션 장애란 무엇입니까?

세그멘테이션 장애란 무엇입니까?C와 C++는 다른가요?분할 장애와 매달린 포인터는 어떻게 관련되어 있습니까?

세그멘테이션 장애는 "사용자 소유가 아닌" 메모리에 액세스하여 발생하는 특정 오류입니다.메모리를 파손하거나 디버깅하기 어려운 메모리 버그가 발생하는 것을 방지하는 도우미 메커니즘입니다.segfault가 발생할 때마다 이미 해방된 변수에 액세스하거나 메모리의 읽기 전용 부분에 쓰는 등 메모리에 문제가 있음을 알 수 있습니다.세그멘테이션 장애는 메모리 관리를 망칠 수 있는 대부분의 언어에서 기본적으로 동일하며, C와 C++의 세그먼트 장애 사이에는 큰 차이가 없습니다.

적어도 C(+)와 같은 하위 수준의 언어에서는 segfault를 얻는 방법이 많이 있습니다.segfault를 취득하는 일반적인 방법은 늘 포인터를 참조 해제하는 것입니다.

int *p = NULL;
*p = 1;

읽기 전용으로 마크된 메모리 부분에 쓰려고 하면 또 다른 seg fault가 발생합니다.

char *str = "Foo"; // Compiler marks the constant string as read-only
*str = 'b'; // Which means this is illegal and results in a segfault

매달린 포인터는 다음과 같이 더 이상 존재하지 않는 것을 가리킵니다.

char *p = NULL;
{
    char c;
    p = &c;
}
// Now p is dangling

" "p에 매달립니다.c블록이 끝난 후 존재하지 않게 되었습니다., 포인터를 해제하려고 를 들면, 「」등).*p='A'가 될 수 있습니다.

세그멘테이션 장애는 다른 프로세스 메모리에 직접 액세스하여 발생하는 것이 아닙니다(이러한 오류는 가끔 듣습니다).그것은 단순히 불가능하기 때문입니다.가상 메모리의 경우 모든 프로세스에는 자체 가상 주소 공간이 있으며 포인터 값을 사용하여 다른 가상 주소 공간에 액세스할 수 없습니다.다른 가상 주소에 (가능성이 있는) 동일한 물리적 주소 공간인 공유 라이브러리와 모든 프로세스에서 동일한 방식으로 매핑되는 커널 메모리가 이에 해당될 수 있습니다(시스템에서 TLB 플래시를 방지하기 위해).그리고 shmat ;)와 같은 것 - 이것들은 제가 '간접' 접근이라고 간주하는 것입니다.그러나 보통 프로세스 코드로부터 멀리 떨어진 곳에 위치해 있으며, 일반적으로 액세스할 수 있는지 확인할 수 있습니다(그래도 잘못된 방법으로 액세스하면 분할 오류가 발생합니다).

다만, 자신의 (프로세스) 메모리에 부적절한 방법으로 액세스 하는 경우(예를 들면, 기입할 수 없는 공간에 쓰려고 하는 경우) 세그멘테이션 장애가 발생할 수 있습니다.그러나 가장 일반적인 이유는 가상 주소 공간의 물리 주소 공간에 전혀 매핑되지 않은 부분에 대한 액세스입니다.

이 모든 것은 가상 메모리 시스템에 관한 것입니다.

세그멘테이션 장애는 프로세스가 기술자 테이블에 나열되지 않은 페이지에 대한 요구 또는 프로세스에 나열되지 않은 페이지에 대한 잘못된 요구(예: 읽기 전용 페이지에 대한 쓰기 요청)로 인해 발생합니다.

행글링 포인터는 유효한 페이지를 가리킬 수도 있고 가리킬 수도 있지만 메모리의 "예상치 않은" 세그먼트를 가리킬 수도 있습니다.

위키피디아에 따르면:

분할 장애는 프로그램이 액세스할 수 없는 메모리 위치에 액세스를 시도하거나 허용되지 않는 방식으로 메모리 위치에 액세스하려고 할 때 발생합니다(예: 읽기 전용 위치에 쓰거나 운영 체제의 일부를 덮어쓰려고 시도하는 경우).

솔직히 말하자면, 다른 포스터들도 언급했듯이 위키피디아는 이것에 대해 매우 좋은 기사를 가지고 있으니 한번 보세요.이러한 유형의 오류는 매우 흔하며 액세스 위반 또는 일반 보호 장애와 같은 다른 오류라고도 합니다.

이들은 C, C++ 또는 포인터를 허용하는 다른 언어에서도 다르지 않습니다.이러한 종류의 오류는 보통 다음과 같은 포인터에 의해 발생합니다.

  1. 올바르게 초기화되기 전에 사용
  2. 가리키는 메모리가 재할당 또는 삭제된 후에 사용됩니다.
  3. 인덱스가 배열 경계를 벗어나는 인덱스 배열에서 사용됩니다.이것은 일반적으로 STL/Boost 기반 컬렉션(C++)이 아닌 기존 어레이 또는 c-string에 대해 포인터 계산을 수행하는 경우에만 해당됩니다.

Wikipedia의 Segmentation_fault 페이지에는 원인과 이유만 기재되어 있습니다.자세한 설명은 Wiki를 참조하십시오.

컴퓨팅에서 세그멘테이션 장애(segfault로 단축되는 경우가 많음) 또는 액세스 위반은 메모리 보호를 갖춘 하드웨어에 의해 발생하는 장애로, 메모리 액세스 위반을 운영체제(OS)에 통지합니다.

부문 화가 잘못의 다음 전형적인 원인은.

  • Dereferencing NULL 포인터 이 기억 장치 관리 하드웨어에 의해special-cased은 –.
  • 는 존재하지 않는 메모리 주소(외부 프로세스의 주소 공간)에 액세스 하려고 하면
  • 에 대한 접근 그 프로그램은 메모리를 하는 것은(커널 구조 등 프로세스 컨텍스트에)권한을 갖지 않는다.
  • 읽기 전용 메모리(코드 세그먼트와 같은) 쓰려고 하면

차례로 이들은 종종 잘못된 메모리 접근에 기인하는 프로그래밍 오류가 발생한다.

  • 또는 초기화되지 않은 포인터(임의로 메모리 주소를 가리키야생 포인터)에 할당하면서 Dereferencing.

  • 또는 자유 포인터(기억에 freed/deallocated/deleted고 있다고 매달려 있는 포인터,)에 할당하면서 Dereferencing.

  • 버퍼 오버 플로

  • 스택 오버 플로

  • 정확하게.(일부 컴파일러는 컴파일 타임 오류의 존재에도 불구하고 실행 파일을 출력합니다.)컴파일하지 않는 프로그램을 실행하려고 하면

간단한 말에 세분화 잘못이야 운영 체제에서는 프로그램이 진행하거나 프로그램이 물든 것에서 메모리를 막기 위해 종료 합니까 불법적인 메모리 접근 감지했다는 신호를 보내고.

세그멘테이션 오류 또한 하드웨어 장애에 의해서, 이 경우 RAM기억 속에 발생합니다.이것은 덜 흔한 이유지만, 만약 여러분이 여러분의 코드가 오류 찾지 못한다면 아마 memtest 당신을 도울 것이다.

이 경우의 해결책, RAM을 바꾼다.

편집:

다음은 참고 자료입니다.하드웨어별 세그멘테이션 장애

다음 코드 조각에 대해 생각해 보십시오.

스니펫

int *number = NULL;
*number = 1;

스니펫 2

int *number = malloc(sizeof(int));
*number = 1;

함수의 malloc() ★★★★★★★★★★★★★★★★★」sizeof()이 질문을 하고 있다면.

이것으로 해결되었습니다.SNIPET 1은 Segmentation Fault Error를 발생시킵니다.반면 스니펫2는 그렇지 않습니다.

그 이유는 이렇습니다.

스니펫의 첫 번째 행은 변수(*number)를 생성하여 다른 변수의 주소를 저장하지만 이 경우 NULL로 초기화됩니다.한편 스니펫2의 두 번째 행은 다른 변수의 주소를 저장하기 위해 동일한 변수(*number)를 생성하며 이 경우 메모리 주소가 지정됩니다(malloc().컴퓨터의 메모리 주소를 반환하는 C/C++)

구입하지 않은 그릇이나 구입은 했지만 사용 허가가 나지 않은 그릇에는 물을 넣을 수 없다는 것이 포인트입니다.이 작업을 시도하면 시스템에 알림이 표시되고 SegFault 오류가 발생합니다.

이 에러는, C/C++ 와 같이 저레벨에 가까운 언어에서만 발생합니다.다른 고급 언어에는 이 오류가 발생하지 않도록 하는 추상화가 있습니다.

또한 Segmentation Fault(분할 결함)가 언어별 결함이 아님을 이해하는 것이 가장 중요합니다.

컴퓨팅에서 세그멘테이션 장애 또는 액세스 위반은 메모리 보호 기능이 있는 하드웨어에 의해 발생하는 장애 또는 장애 상태이며 소프트웨어가 제한된 메모리 영역에 액세스하려고 시도했음을 운영 체제에 알립니다.-Wikipedia

잘못된 데이터 유형으로 컴퓨터 메모리에 액세스하고 있을 수 있습니다.다음과 같은 경우가 있습니다.

#include <stdio.h>

int main(int argc, char *argv[]) {
    
    char A = 'asd';
    puts(A);
    
    return 0;
    
}

'문자' ->는 단일 문자 데이터 형식이 아닌 문자 체인입니다.따라서 이를 char로 저장하면 분할 오류가 발생합니다.일부 데이터를 잘못된 위치에 저장했습니다.

저장 ★★string 단일 문자 할 수 있습니다.char동그란 구멍에 네모난 못을 박으려고 하는 거야

신호로 인해 종료됨: Segmentation FAULT(11)

Segm. 잘못은 물속에서 숨을 들이마시려는 것과 같아. 너의 폐는 그렇게 만들어지지 않았어.정수를 위해 메모리를 예약한 다음 다른 데이터 유형으로 작동하려고 하면 전혀 작동하지 않습니다.

답변에는 "세그멘테이션 장애"에 대한 몇 가지 좋은 설명이 있지만, 세그멘테이션 장애에서는 메모리 컨텐츠 덤프가 발생하는 경우가 많기 때문에 세그멘테이션 장애(코어 덤프됨)의 "코어 덤프됨" 부분과 메모리의 관계가 어디에서 비롯되는지 알려드리고자 합니다.

반도체 메모리 이전인 1955년부터 1975년까지 컴퓨터 메모리의 지배적인 기술은 구리선에 매달린 작은 자기 도넛을 사용했다.도넛은 "페라이트 코어"로 알려졌으며 메인 메모리는 "코어 메모리" 또는 "코어"로 알려졌습니다.

여기서부터 가져갑니다.

세그멘테이션 폴트의 정의는 충분합니다.프로그래밍을 하다가 우연히 접한 몇 가지 예를 들겠습니다.실수라고 생각될 수 있지만 많은 시간을 낭비하게 됩니다.

  1. 아래의 경우 인수 유형이 일치하지 않는 동안 세그멘테이션 장애가 발생할 수 있습니다.printf:
#include <stdio.h>
int main(){   
  int a = 5;
  printf("%s",a);
  return 0;
}

출력:Segmentation Fault (SIGSEGV)

  1. 포인터에 메모리를 할당하는 것을 잊은 경우, 포인터를 사용해 보십시오.
#include <stdio.h> 
typedef struct{
  int a;
} myStruct;   
int main(){
  myStruct *s;
  /* few lines of code */
  s->a = 5;
  return 0;
}

출력:Segmentation Fault (SIGSEGV)

간단한 의미Segmentation fault자신의 것이 아닌 어떤 기억력에 접근하려고 한다는 것입니다. Segmentation fault읽기 전용 메모리 위치에서 읽기 및 쓰기 작업을 시도하거나 메모리를 비우려고 할 때 발생합니다.즉, 우리는 이것을 일종의 기억의 손상이라고 설명할 수 있다.

아래에서는 프로그래머가 저지르는 일반적인 실수를 언급하고 있습니다.Segmentation fault.

  • 사용하다scanf()잘못된 방법으로(말하기 어렵다)&).
int num;
scanf("%d", num);// must use &num instead of num
  • 포인터를 잘못된 방법으로 사용합니다.
int *num; 
printf("%d",*num); //*num should be correct as num only
//Unless You can use *num but you have to point this pointer to valid memory address before accessing it.
  • 문자열 리터럴 수정(포인터는 읽기 전용 메모리 쓰기 또는 수정을 시도합니다.)
char *str;  

//Stored in read only part of data segment
str = "GfG";      

//Problem:  trying to modify read only memory
*(str+1) = 'n';
  • 이미 해방된 주소를 통해 접속을 시도합니다.
// allocating memory to num 
int* num = malloc(8); 
*num = 100; 

// de-allocated the space allocated to num 
free(num); 

// num is already freed there for it cause segmentation fault
*num = 110; 
  • 스택 오버플로우: 스택의 메모리가 부족합니다.
  • 범위를 벗어난 배열에 액세스합니다.
  • 사용할 때 잘못된 형식 지정자 사용printf()그리고.scanf()'

세그멘테이션 장애는 프로세스(프로그램의 실행 인스턴스)가 다른 프로세스에서 사용되는 읽기 전용 메모리 주소 또는 메모리 범위에 액세스하려고 하거나 존재하지 않는(잘못된) 메모리 주소에 액세스하려고 할 때 발생합니다.Dangling Reference(포인터) 문제는 내용이 메모리에서 이미 삭제된 개체 또는 변수에 액세스하려고 시도하는 것을 의미합니다. 예를 들어 다음과 같습니다.

int *arr = new int[20];
delete arr;
cout<<arr[1];  //dangling problem occurs here

"세그멘테이션 장애"는 액세스할 수 없는 메모리에 액세스하려고 시도했음을 의미합니다.

첫 번째 문제는 당신의 주장입니다.주요 기능은 다음과 같습니다.int main(int argc, char *argv[])argv[1]에 액세스하기 전에 argc가 적어도2인지 확인해야 합니다.

또한 flot을 printf로 전달하고 있기 때문에(단, printf로 전달하면 2배로 변환됩니다), %f 형식 지정자를 사용해야 합니다.%s 형식 지정자는 문자열('\0' 끝 문자 배열)입니다.

분할 장애 또는 액세스 위반은 프로그램이 존재하지 않는 메모리 위치에 액세스하려고 하거나 허용되지 않는 방법으로 메모리 위치에 액세스하려고 할 때 발생합니다.

 /* "Array out of bounds" error 
   valid indices for array foo
   are 0, 1, ... 999 */
   int foo[1000];
   for (int i = 0; i <= 1000 ; i++) 
   foo[i] = i;

여기서 i[1000]는 존재하지 않기 때문에 segfault가 발생합니다.

분할 결함의 원인:

it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.

De-referencing NULL pointers – this is special-cased by memory management hardware.

Attempting to access a nonexistent memory address (outside process’s address space).

Attempting to access memory the program does not have rights to (such as kernel structures in process context).

Attempting to write read-only memory (such as code segment).

언급URL : https://stackoverflow.com/questions/2346806/what-is-a-segmentation-fault

반응형