컴파일러, 어셈블러, 기계 명령어 등과 같은 컴퓨터 프로그래밍의 하위 구성 요소가 완벽하다는 것을 어떻게 확신 할 수 있습니까?


57

우리는 일상 생활의 매우 중요한 작업을 포함하여 컴퓨팅에 점점 더 의존하고 있기 때문에 중요한 구성 요소를 어떻게 테스트하는지 궁금했습니다.

보다 기술적으로 컴파일러와 어셈블러는 어떻게 테스트됩니까? (이것은 정지 문제 와 관련이 있다고 가정합니다 !!)


36
"켄 톰슨 핵"으로 연구를 시작하고 싶을 수도 있습니다 . 신뢰 신뢰에 대한 고찰
Bryan Oakley

7
다음은 정확성 증명이있는 컴파일러의 예입니다. compcert.inria.fr/doc/index.html
Giorgio

8
대부분의 컴파일러 / 링커 / 어셈블러는 다양한 환경에서 많이 사용하여 가장 깊이 테스트됩니다. 오류를 찾기 위해 컴파일러를 사용하는 수백만 명의 사용자를 갖는 것은 없습니다.
Bart van Ingen Schenau

3
운영 체제를 목록에 추가하십시오.
Erik Eidt

답변:


104

확신 할 수는 없지만, 그렇지 않다는 것을 발견 할 때까지는 그냥 있다고 가정합니다. 수년 동안 컴파일러와 하드웨어에 많은 버그가있었습니다.

예를 들어 컴파일러와 같은 테스트 방법은 매우 좁고 엄격하게 정의되고 신중하게 작성된 다음 거대 테스트 스위트로 테스트하여 정확성을 확인하는 것입니다. 거기에 컴파일러의 광범위한 사용자 기반을 추가하면 더 많은 버그가 감지되고보고됩니다. 치과 의사 예약 일정 앱은 비교적 적은 수의 사용자를 보유하고 있으며 결함을 감지 할 수있는 사용자는 여전히 적습니다.

SQLite는 약 73k 줄의 코드로 구성되며 테스트 스위트는 약 91378k 줄의 코드로 구성되며 SQLite 자체의 1250x 배 이상입니다. 컴파일러와 다른 핵심 도구의 비율이 비슷할 것으로 기대합니다. 오늘날 프로세서는 기본적으로 Verilog 또는 VHDL과 같은 하드웨어 설명 언어를 사용하여 소프트웨어를 사용하여 설계되었으며, 소프트웨어 테스트는 물론 자체적으로 테스트를 수행하기위한 특수 IO 핀도 실행됩니다.

궁극적으로 그것은 확률 게임이며 반복적이고 광범위하게 테스트를 통해 결함 가능성을 다른 소프트웨어 프로젝트와 마찬가지로 허용 가능한 낮은 수준으로 낮출 수 있습니다.


7
나는 종종 OP와 같은 질문을 궁금해했지만 DBMS와 관련하여. SQLite의 맥락에서 그에 대한 훌륭한 예를 들었습니다. 감사합니다!
Brandon

7
+1이지만 "컴파일러 및 기타 핵심 도구의 비율이 비슷합니다"라고 의심합니다.
Mehrdad

5
(1) SQLite에는 실제로 두 개의 테스트 스위트가 있으며, 둘 사이에 사소한 중복성이 없으며 (2) 그럼에도 불구하고 SQLite에는 여전히 버그가 있습니다.
Matthieu M.

7
SQLite는 많은 컴파일러들보다 일반적인 용도로 사용할 수있는 가장 광범위하게 테스트 된 소프트웨어 (테스트 코드 라인 / 운영 코드 라인 측면) 중 하나라는 인상을 받았습니다. 다른 기능이 없다면 완전한 기능을 갖춘 컴파일러는 엄청난 양의 소프트웨어이므로 테스트 코드보다 1000 배나 많은 것을 상상할 수 없습니다. (GCC는보고 된 최대 1,450 만 라인입니다. 적절한 컴파일러 컬렉션이 14k LOC에 불과하거나 측면에 14 억 라인 테스트 코드베이스가있는 것 같지 않습니다! :-P)
David Z

2
@DavidZ : 그것은 확실히 광범위한 OOM 테스트를 사용하는 것으로 알고있는 유일한 프로젝트입니다. 실행됩니다).
Matthieu M.

46

평신도의 관점에서 :

  1. 당신은 할 수 없습니다.
  2. 컴파일러와 인터프리터는 다른 (전문) 소프트웨어로 단위 테스트를 거쳤습니다.
  3. 테스트에 성공했다고해서 프로그램에 버그가없는 것은 아니며 버그가 발견되지 않았 음을 의미합니다.
  4. 오랫동안 컴파일러를 사용하는 광범위한 사용자 기반은 버그가 거의 없다는 것을 나타내는 훌륭한 지표입니다. 사용자는 일반적으로 설계자가 생각하지 않은 사례를 테스트하기 때문입니다.
  5. 오픈 소스라는 것도 좋은 지표입니다. "충분히 안구가 생기면 모든 버그가 얕아진다. 충분히 큰 베타 테스터와 공동 개발자 기반을 고려할 때, 거의 모든 문제는 신속하게 특성화 될 것이며 수정은 누군가에게 명백 할 것이다." . 비공개 소스 컴파일러에는 매우 특정한 시간에 발생하거나 최적의 머신 코드보다 덜 생성되는 버그가있을 수 있으며 그 뒤에있는 회사는 단순히 존재 여부를 공개하지 않고 제품 로드맵에서 우선 순위가 매우 낮습니다.

결론 :

나는 OOP 갈 (말하고 싶지만 O의 LD, O의 펜과 P의 opular). 방금 그 약어를 만들었습니다.


19
+1 다른 TLA (세 글자 약어)를 발명 한 결과, 세계에는 아직 부족합니다.
s1lv3r

34
또한 OOP는 아직 컴퓨터 프로그래밍에 의미가 없었습니다. 그래서 KTT (귀하 께 당신에게)!
Pierre Arlaud

15
Pierre의 의견은 @Dannnno의 농담입니다.
yannis

19
또는 P opular, O ld 및 O pen이 ​​될 수 있습니다. ;) 사실, 그것이 중요한 순서대로 순위를 매기는 방법입니다.
jpmc26

23
@ jpmc26 실용적이며 오래되고 개방적이며 인기가 있습니다. 약어에 대해 ...
StupidOne

24

거북은 끝이야

확실하지 않습니다. 신뢰 등급을 정하는 것 외에는 선택의 여지가 없습니다.

스택으로 생각할 수 있습니다 : 수학> 물리학> 하드웨어> 펌웨어> 운영 체제> 어셈블러 / 컴파일러 / 등

각 수준마다 신뢰 등급을 높이기 위해 수행 할 수있는 테스트가 있습니다. 이러한 테스트 중 일부는 공식적인 증거의 품질을 가지며 일부는 관찰을 기반으로하며 대부분 둘 다의 조합입니다.

까다로운 부분은 이러한 테스트 중 일부에서 재귀를 풀고 있습니다. 우리는 프로그램을 사용하여 손으로하기가 너무 어려워진 증거 및 관찰 분석을 수행하기 때문입니다.

궁극적으로 대답은 당신이 생각할 수있는 모든 것을 시도한다는 것입니다. 정적 분석, 퍼징, 시뮬레이션, 의도적으로 선택된 극한의 입력 또는 임의의 입력으로 실행, 모든 제어 경로를 실행 / 매핑, 공식적인 증거 등 기본적으로 테스트의 목표는 항상 제품 (예 : 이론 / 칩 / 프로그램)이 의도 한대로 작동하지 않습니다. 진심으로 노력했지만 여전히 실패하면 제품의 정확성에 대한 신뢰도를 향상시킬 수 있습니다.

테스트는 기껏해야 반 결정 과정을 의미합니다. 결국 버그를 발견했을 때 버그를 발견 할 수 있지만 모든 것을 발견했다고 확신 할 수는 없습니다. 공식적으로 검증 된 소프트웨어를 사용하더라도 여전히 물리학, 공식적인 증명을 수행하는 데 사용되는 도구 및 프로그램이 "주관적으로"의도 된대로 수행하기에 충분하고 충분하다는 사실에 의존하고 있습니다. 공식적인 증거가없는 사용중인 다른 모든 구성 요소는 말할 것도 없습니다.


17

이것은 새로운 개발자가 코드 대신 도구를 비난하기 시작한다는 점에서 "위험한"질문입니다 (그러면 너무 많은 것으로 보임). 컴파일러, 런타임 환경, OS 등에 버그가 있지만 개발자는 현실적으로 알고 있어야하며 그렇지 않은 경우를 보여주는 증거 및 단위 테스트가있을 때까지 버그는 코드에 있습니다.

주로 C, C ++ 및 Java에서 25 년 이상 프로그래밍을 수행 한 결과 다음과 같습니다.

  • 컴파일러 버그로 인한 두 가지 버그 (gcc 및 SunOS C)
  • Java JVM 문제 (일반적으로 메모리 소비 / 가비지 콜렉션 관련)로 인해 매년 약 1-2 회 버그
  • 라이브러리에서 한 달에 한두 번 버그가 발생합니다.이 버그는 최신 버전을 사용하거나 이전 버전의 라이브러리로 되돌려 서 자주 수정됩니다.

다른 모든 버그는 버그 또는 라이브러리 작동 방식에 대한 이해 부족과 직접 관련이 있습니다. 때때로 버그로 보이는 것은 비 호환성 때문입니다. 예를 들어 Java 클래스 구조가 어떻게 변경되어 일부 AOP 라이브러리가 손상 되었습니까?


궁금합니다. 몇 년 동안 어떤 언어를 사용합니까? 돌아 가기 C ++ 전에 EGCS 일에 제대로 ... 컴파일러 버그 찾기가 너무 힘들어하지 않았다, 표준화 된
찰스 더피에게

3
컴파일러, CPU 또는 언어가 모호할수록 컴파일러에서 버그를 쉽게 찾을 수 있으므로 (다른 사람보다 먼저) GCC C에서 2를 찾는 것이 좋습니다 :)
Surt

1
그것이 일어날 때, 나는 gdb 스크립트에 있었던 문제 또는 내가 조사하고있는 것에 대한 이해를 가정하여 약 한 달 동안 낭비했습니다. 결국 나는 의심스러워하고 테스트 사례를 단순화했으며 라이브러리 (libkvm)에서 디자인 결함을 발견하여 커널 디버거가 코어 덤프에서 특정 주소에 액세스 할 수 없었습니다. 즉 YMMV-코드 업스트림에서 새로운 버그, 특히 개발하기보다는 사용중인 버그를 발견하면 가장 행복합니다.
Arlie Stephens

물론 이것은 컴파일러 버그 가 아니 거나 더 일반적으로 사용되는 라이브러리 중 하나 가 아닙니다 . 그리고 진실은, 나는 어떤 빈도로도 버그를 찾지 않습니다.
Arlie Stephens

@ArlieStephens 여기에는 교훈이 있습니다. 테스트 사례를 단순화하는 것은 문제를 찾는 데 실패했을 때 초기에해야 할 일입니다. 문제가 자신의 문제인지 다른 코드의 문제인지에 관계없이 문제를 좁히는 데 도움이됩니다. 문제가 다른 코드에있는 경우 종종 "증거 및 단위 테스트 시연"이 발생합니다.
jpmc26

8

여기서 흥미로운 점은 대다수의 상용 소프트웨어 (및 실제로는 오픈 소스 소프트웨어) 라이센스가 소프트웨어를 신뢰할 수 없음을 구체적으로 명시하고 있다는 것입니다.

본 소프트웨어는 상품성, 특정 목적에의 적합성 및 비 침해에 대한 보증을 포함하되 명시 적이든 묵시적이든 어떠한 종류의 보증없이 "있는 그대로"제공됩니다.

Microsoft Word 라이센스 계약에서

. 제한 보증을 제외하고 관련 법률이 허용하는 최대 범위를 제외하고 Microsoft 및 해당 공급 업체는 소프트웨어 결함 및 지원 서비스 (있는 경우)를 모든 결함과 함께 제공하며, 명시 적이든 묵시적이든 기타 모든 보증 및 조건을 부인합니다. 묵시적 보증, 상업성, 특정 목적에의 적합성, 신뢰성 또는 가용성에 대한 적합성, 응답의 정확성 또는 완전성, 결과, 작업과 같은 노력의 암시 적 보증, 의무 또는 조건을 포함하지만 이에 국한되지 않는 법정 소프트웨어와 관련된 모든 바이러스 및 과실의 부족, 소프트웨어를 통해 또는 소프트웨어 사용으로 인해 발생하는 지원 또는 기타 서비스, 정보, 소프트웨어 및 관련 컨텐츠 제공 또는 제공에 실패 .

본질적으로 귀하가 사용하는 거의 모든 소프트웨어에있는 라이센스의이 문장은 사용 된 컴파일러는 물론 소프트웨어를 신뢰할 수 없음을 나타냅니다.

소프트웨어는 과학적 이론과 같으며, 그렇지 않을 때까지 지정된대로 작동하는 것으로 간주됩니다.


라이센스가 소프트웨어가 완벽하지 않다고 지적한 +1.
Tulains Córdova

3
IBM의 ViaVoice for Mac에서이 관행에서 벗어난 점에 대해 기쁘게 생각합니다. 그들은 "작동하지 않으면 너무 나쁘다"는 관습 대신에 실제로 "소프트웨어는 지정된대로 수행하도록 보증합니다."
WGroleau

1
이 특정 보증 문구에 대한 일반 언어 번역은 "이것은 소프트웨어 일 수도 있고 sh * t 일 수도 있습니다. 작동 할 수도 있습니다. 작동하지 않더라도 작동하지 않을 수도 있습니다. 어쨌든, 우리는 다른 사람으로부터 약간의 돈을 훔 쳤을 수도 있습니다 .. 너무 나쁩니다. 우리는 돈을 가지고 많은 변호사를 고용하기 위해 그것을 사용했습니다. 게임! -nyah-nyah-nyaaah-naah! ". :-)
Bob Jarvis

2
@BobJarvis : nmap IIRC와 같은 일부 오픈 소스 소프트웨어에 사용 된 제가 가장 좋아하는 보증서는 "만약 그것이 깨지면 두 조각을 모두 유지해야합니다"입니다.
Peter Cordes

이 진술은 오픈 소스 소프트웨어와 많은 무료 비공개 소스 소프트웨어에 편재되어 있습니다. 대부분의 상용 유료 소프트웨어 라이센스에는 나타나지 않습니다.
jwg

2

수학 언어 *의 컴파일러 라이터로서, 내 경험으로는 이론 상으로는 말할 수 없습니다. 그리고 일부 버그는 (나의 수치 목록에서) 6/3*2오른쪽에서 계산 하고 6/(3*2)충돌하지 않거나 무의미한 컴파일 오류를 발생시키지 않고 1을 출력하는 것과 같은 잘못된 결과를 제공합니다.

그러나 IMHO 많은 컴파일러에는 다음과 같은 이유로 다른 소프트웨어만큼 많은 버그가 없습니다.

  • 단위 테스트 작성이 쉽습니다. 각 문장은 하나의 단위이며 다음과 같이 간단하게 테스트를 작성할 수 있습니다.test_unit("2+(-2)*(-2+1)*3+1",9);
  • 프로그램은 명령문의 조합이며 모든 프로그램에서 올바른 결과를 출력하기 위해 각 개별 명령문이 올바른 결과를 제공해야합니다 (대부분). 따라서 프로그램이 올바른 결과를 제공하는 동안 버그가 발생할 가능성은 거의 없습니다.
  • 작성된 프로그램의 크기와 수가 증가함에 따라 버그를 잡을 가능성이 크게 증가합니다.

어셈블러, 기계 명령어 등의 경우 위도 마찬가지입니다. 반면에 칩 설계 및 생산의 검증 및 검증은 전자 비즈니스 자동화 라는 큰 사업이기 때문에 훨씬 더 엄격한 프로세스를 가지고 있습니다 .

생산을 시작하기 전에 각 버그는 거의 2 백만 달러에 달하기 때문에 각 CPU를 엄격하게 테스트해야합니다. 칩 생산에는 반복적이지 않은 생산 비용이 있습니다. 따라서 Pentium FDIV 버그와 같이 100 % 보증을 제공하지는 않지만 회사는 생산을 시작하기 전에 많은 돈을 소비하고 디자인을위한 많은 시뮬레이션 코드를 작성합니다.

간단히 말해서 컴파일러, 머신 코드 등에 심각한 버그가있을 가능성은 거의 없습니다.

내 겸손한 수학 언어 *


인텔은 임의의 명령 시퀀스를 실행하고 소프트웨어 모델과 비교하여 tweakers.net/reviews/740/4/… 와 같은 CPU에서 지옥을 테스트합니다 . 그렇기 때문에 특이한 모드에서 명령어 조합이 거의 불가능하기 때문에 종종 정오표가 잘못 표시되는 경우가 있습니다.
Peter Cordes

0

완벽한? 그들은 아니야. 최근에 몇 가지 "업데이트"를 설치했으며, 여러 기본 사항이 작동하거나 실패하는 방식에 대한 설명이 변경되지 않았기 때문에 ASP.NET 사이트가 다시 제대로 작동하기까지 몇 개월 (그리고 프로그래밍 된 여러 코드 섹션)이있었습니다.

그러나, 그들은 대부분의 것을 알아 차리고보고하고 고치는 경향이있는 매우 똑똑한 디테일 지향적 인 많은 사람들에 의해 테스트되고 사용됩니다. Stack Exchange는 이러한 도구를 사용하는 모든 사람들이 최소한 실제적으로 사용하는 한 놀랍도록 복잡하고 낮은 수준의 도구가 어떻게 작동하는지 테스트하고 분석하는 데 도움이되는 훌륭한 예입니다.

그러나 완벽합니다. Stack Exchange 직원이 성능 세부 사항 및 표준 준수 및 단점에 대한 인상적인 통찰력을 얻는 것을 볼 수도 있지만, 특히 다른 사람이 결함에 대해 다른 의견을 가지고있는 경우에는 항상 결함과 결함이 있습니다.


-1

기본 시스템이 완벽하다는 것을 보여주기 위해

a) 결함이 없음을 증명해야합니다.

  1. 수학적 증거
  2. 사소한 프로그램에 대해서만 현실적으로 가능

b) 철저한 테스트

  1. 사소한 프로그램 및 일부 간단한 프로그램에만 가능
  2. 타이밍 요소가 테스트에 들어가 자마자 시간을 무한정 나눌 수 있으므로 철저한 테스트를 수행 할 수 없습니다.
  3. 사소한 프로그램 외에도 가능한 실행 옵션이 기하 급수적으로 폭발합니다.

소프트웨어 테스트에서 철저한 테스트는 일부 간단한 기능의 단위 테스트에만 사용됩니다.

예 : 일부 필드에 8 문자 utf-8 입력을 테스트하려면 utf-8의 최대 길이 6의 8 배에서 바이트 단위로 입력을 자르도록 선택하십시오. 이는 실제로 8 * 6 = 48 바이트를 제공합니다. 유한 한 가능성.

이제 8 개 문자 각각의 1,112,064 개의 유효한 코드 포인트 만 테스트하면 된다고 생각할 수 있습니다 . 1,112,064 ^ 8 (10 ^ 48) 테스트 (이미 가능하지는 않지만) 실제로는 48 바이트 또는 256 ^ 48 각각의 각 값을 테스트해야합니다 .10 ^ 120은 체스 와 같은 복잡성 입니다. 우주에서 대략 10 ^ 80의 총 원자 수에 비해.

대신 노력을 늘리면서 사용할 수 있으며 각 테스트는 이전의 모든 테스트를 포함해야합니다.

a) 좋은 샘플과 나쁜 샘플을 테스트합니다.

b) 코드 적용 범위, 즉 모든 코드 줄을 테스트하십시오. 이는 대부분의 코드에서 상대적으로 간단합니다. 이제 테스트 할 수없는 코드의 마지막 1 %가 무엇인지 궁금해 할 수 있습니다 ... 버그, 죽은 코드, 하드웨어 예외 등

c) 경로 범위, 모든 조합에서 모든 분기의 모든 결과가 테스트됩니다. 이제 함수에 10 개가 넘는 조건이 포함 된 경우 테스트 부서가 왜 싫어하는지 알 수 있습니다. 또한 마지막 1 %를 테스트 할 수없는 이유가 궁금합니다. 일부 분기는 이전 분기에 따라 다릅니다.

d) 데이터 테스트, 보더 값, 일반적인 문제 값 및 마법 수, 0, -1, 1, 최소 +/- 1, 최대 +/- 1, 42, rnd 값으로 다수의 샘플을 테스트합니다. 이것이 경로 적용 범위를 제공하지 않으면 분석의 모든 값을 파악하지 못한 것입니다.

이미이 작업을 수행 한 경우 ISTQB 기초 시험을 준비해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.