나무모에 미러 (일반/어두운 화면)
최근 수정 시각 : 2023-01-27 16:07:34

오버플로


파일:나무위키+유도.png  
은(는) 여기로 연결됩니다.
동음이의어에 대한 내용은 오버플로(동음이의어) 문서
번 문단을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
, 에 대한 내용은 문서
번 문단을
번 문단을
부분을
부분을
참고하십시오.
1. 개요2. 분류
2.1. 10진수 오버플로2.2. 8비트 오버플로2.3. 16비트 오버플로2.4. 32비트 오버플로2.5. 기타
3. 관련 문서

1. 개요

파일:external/imgs.xkcd.com/cant_sleep.png
xkcd 571화 'Can't Sleep'
32767에서 -32768로 나가는 걸로 봐서 이 예시에서 양의 수는 부호 있는 2바이트 정수 형태(short)로 저장되는 모양이다.
파일:기계식 체중계 오버플로.jpg
기계식(아날로그) 체중계가 측정 범위를 넘어버린 모습. 실제 무게는 131.5kg일 것이다. 오버플로임을 감안해도 하루만에 15kg 가까이 찐 셈.
파일:IMG_6133~2.png
지구종말 네이버 날씨에서 모종의 오류로 오버플로가 발생한 상황.

Overflow

컴퓨터의 정수 연산의 계산 결과가 허용 범위를 초과할 때 발생하는 오류.

컴퓨터의 메모리가 8비트의 데이터를 저장할 수 있다고 하고, 편의상 부호는 없는 양수인 경우만 고려해 보자. 가장 작은 값은 0000 0000 (=0) 이며, 1씩 증가시키면 0000 0001 (=1)을 거쳐 최댓값인 1111 1111 (=255)에 도달하게 된다. 여기에서 1을 다시 한번 더하게 되면 최댓값의 범위를 넘어서게 되고, 최솟값인 0000 0000 (=0) 으로 되돌아가게 된다. 이를 오버플로라고 부른다.

이는 2의 보수를 사용하는 부호형 정수 방식(signed integer)에서도 동일하며, 8비트 정수형은 -128 ~ 127 사이의 값을 저장할 수 있다. 그런데, 0111 1111 (=127) 에서 1을 더하게 되면 1000 0000 인데, 이는 -128 이 된다. 이 역시 최댓값의 범위를 넘어서서 가장 작은 값으로 바뀌는 것이다.

32비트 부호형 정수형이라면 -2147483648 ~ 2147483647 이며, 이 경우에도 2147483647 + 1 은 허용범위를 초과하므로 최솟값인 -2147483648 가 된다. 반대로, 정수의 최솟값에서 1을 뺄 경우에는 최댓값이 되어 버린다. 즉 -2147483648 - 1 = 2147483647 이 된다. 일부 사람들이 이 경우를 '언더플로'라고 부르지만 잘못된 표현이며, 이 경우 또한 오버플로다. 양이건 음이건 범위를 벗어나면 모두 오버플로이다. 산술 언더플로(Arithmetic underflow)는 부동소수점 연산에서 지수부가 타입의 한계를 넘어 작아지면 0에 가까워지다가 결국 0이 되어버리는 현상을 의미한다. [1]

오버플로의 가장 많은 예로 스택 오버플로(Stack Overflow)가 있다. 함수는 변수 등을 저장하기 위해 스택이라는 메모리 공간을 만드는데, 이 함수가 재귀적으로 계속 실행되면 스택이 점점 생겨난다. 이러면 어느 순간 메모리가 모자라는 순간이 되는데 이때 생기는 오류다. 프로그래밍 언어를 만들 때, 이 스택 오버플로가 잘 일어나지 않도록 하는 것도 일이다. 응용형으로 버퍼 오버플로(Buffer overflow)가 있다. 할당된 범위의 메모리를 벗어난 주소로 접근하게 되는 것으로, 하트블리드 사태도 이런 버퍼 오버플로로 벌어진 것이다.

컴퓨터 또는 프로그래밍 언어의 동작에 따라, 오버플로 발생 시 오류 메시지를 출력하는 경우도 있고[2], 그러지 않는 경우도 있다. 이 중 오류 메시지를 출력하지 않는 경우가 더 위험하다. 잘못된 정보로 명령을 계속 수행하므로 잘못된 값을 출력하거나 오류 메시지를 출력하는 곳과 오버플로가 일어난 곳이 다른 일이 일어날 수가 있다. 일부 프로그래밍 언어의 경우는 오버플로가 일어나지 않도록 언어 자체적으로 보완책을 가지는 경우도 존재한다.

2. 분류

2.1. 10진수 오버플로

10진수 기반 시스템에서 발생하는 오버플로다.


최대 9999까지 표현 가능한 기기에서 9999에 1을 더할 때 발생하는 10진수 오버플로.

파일:무료입니다.gif
무슨 차길래 기름이 1000달러나 들어가는...[3]

초창기의 컴퓨터는 BCD(Binary Coded Decimal) 나 EBCDIC(Extended Binary Coded Decimal Interchange Code)이라 불리는 10진수 기반의 수체계를 사용했다. 또한, 이 당시에 사용하던 코볼(COBOL) 같은 컴퓨터 언어도 이런 수체계 기반을 사용하도록 만들어져 있었다. 그래서, 99나 999를 넘어가면 100이나 1000이 되는 것이 아니라 0이 되어버리는 버그가 존재했다.

이로 인해서 가장 문제가 되었던 것이 바로 Y2K 문제이다. 년도 저장을 위해서 2자리의 십진수 정수형만 사용하다 보니 (19)99년 다음에 2000년이 되어야 하는데 (19)00년이 되어 버리는 버그다.

2.2. 8비트 오버플로

8비트 정수의 저장 범위는 최상위 비트를 음수 부호로 사용하는(signed) 경우 -128 ~ 127이고, 음수 부호를 사용하지 않는(unsigned) 경우 0 ~ 255이다. 255나 127을 넘어 갈 경우 오버플로가 발생한다.

2.3. 16비트 오버플로

16비트 정수의 저장 범위는 -32768 ~ 32767(signed) 또는 0 ~ 65535(unsigned)이다. 65535나 32767을 넘어갈 경우 오버플로가 발생한다.

2.4. 32비트 오버플로

32비트 정수의 저장 범위는 대략 -231 ~ 231-1(signed) 또는 0 ~ 232-1(unsigned)까지이다. 이 값을 넘어 갈 경우 오버플로가 발생한다. 이 값들을 풀어 쓰면 42949672952147483647인데, 관련 버그에서 흔히 등장하는 값이다.

2.5. 기타


여러 기기의 설정 가능한 최대 날짜를 넘겨서 오버플로를 실험해보는 영상. 각종 OS, 전자기기, 프로그래밍 언어를 테스트했다.[9]

3. 관련 문서



[1] 하지만, 정수 자료형에서 최댓값에서 최솟값으로 넘어가는 오버플로와 구분하기 위해 언더플로라는 용어를 혼용해서 사용하고 있는데, 명확하게 하기 위해서는 '정수 언더플로'(Integer underflow)라는 용어를 사용해 산술 언더플로와 다르다는 것을 명시하는 것이 좋다.[2] 프로그래머가 코딩을 하며 catch, try 등으로 예외 처리를 했으면 오류 메세지가 뜬다. 보통은 '메모리가 XXXXXX~YYYYYY 값을 초과하였습니다. 이 메모리는 read될 수 없습니다' 와 같이 뜬다.[3] 보험 가입이 거부되는 호머를 보고 마지의 강박적인 절약으로 인해 생긴 돈을 빼돌려 구매한 캠핑카이다. 뒤의 조금 작은 00은 센트 단위다.[4] 여기서 월드를 나타내야 할 칸이 빈칸으로 나오는 것도 오버플로 때문인데, 사실은 월드 36이지만 프로그램에서는 36을 빈칸으로 인식하여 나타나는 것이다.[5] 9시간 6분 8초이다.[6] 이때 얻는 캡의 갯수는 65535에서 가지고 있는 칩 갯수를 뺀 만큼 얻는 지라 칩이 32768캡에 가까울수록 얻는 캡이 많아진다.[예시] /give @p diamond_sword{Enchantments:[{id:"sharpness",lvl:32767}\]} 라고 입력하면 날카로움 32767의 다이아몬드 검을 얻지만, /give @p diamond_sword{Enchantments:[{id:"sharpness",lvl:32768}\]} 이라고 입력하면 날카로움 -32768의 검을 얻게 된다. 때리면 몬스터가 치료되는 마법의 검.[8] 엄밀히 말하면 두 터치 간격이 30ms 이하여야 한다.[9] 기기에 따라 반응이 다른데, 무한정으로 늘어나거나, 기기에 저장된 가장 이른 날짜로 설정되거나, 아니면 설정할 수 있는 최대치 이후의 날짜로 옮겨가기도 한다.[10] 게다가 이 기기의 코드는 단 한 명의 아마추어 코더가 작성한 것으로 밝혀졌고, 이 일련의 사태 이후 FDA는 의료기기에 쓰이는 코드 다큐멘테이션을 의뮤화한다. 오늘날 이 사태는 IT 윤리 분야에서 널리 인용되는 케이스로 남아있다.