코드가 처음부터 "관리"되지 않은 이유는 무엇입니까?[닫은]

StackOverflow https://stackoverflow.com/questions/796931

  •  18-09-2019
  •  | 
  •  

문제

이것은 Microsoft가 관리 코드 개념을 전파하기 위해 추진하고 있는 .NET CLR에 관한 것이 아닙니다.여러분 대부분은 관리 코드가 꽤 오랫동안 사용되어 왔으며 로켓 과학과 별로 관련이 없다는 것을 알고 있습니다.

내가 알고 싶은 것은 컴퓨터 발전 과정에서 런타임 보안 개념이 그토록 늦게 등장한 이유.

나는 이것이 "왜 최초의 Model T Ford에는 에어백과 안전 벨트가 장착되지 않았습니까?"라고 묻는 것과 같다는 것을 알고 있습니다.그럼에도 불구하고 질문의 관련성은 여전히 ​​유효합니다. 왜냐하면 알려진 위험으로부터 보호하는 것은 인간 본성 내에 있기 때문입니다.예:최초의 T-Ford는 에어백 연구에 동기를 부여할 만큼 빠르지 않았습니다.사람들이 치명적인 판단 오류를 너무 자주 저지르기 때문에 많은 국가에서 안전벨트를 법과 표준으로 삼을 만큼 속도가 빠르지 않았습니다.

컴퓨터 진화에서는 거의 그 반대입니다.우리는 어셈블러로 시작했습니다. 이는 안대를 착용하고 T-Ford를 시속 200mph로 운전하는 것과 같습니다.나는 이 시대의 몇몇 노련한 트럭 운전자들과 대화하면서 손으로 조립하는 어셈블리 코드, 인간 디버거, 그릴리언 코드 라인 등에 대한 이야기를 듣는 즐거움을 누렸습니다.C에서 정말 심각한 오류를 범하면 블루스크린이 발생할 수 있습니다.수십 년 전에는 하드웨어가 손상될 수 있었는데, 그 사실은 신만이 알 수 있습니다.하지만 그것은 나에게 미스테리입니다. 수십 년 동안 충돌을 덜 고통스럽게 만들기 위해 우리가 한 일은 블루스크린뿐이었습니다(MS를 원형으로 사용해서 죄송합니다).

알려진 위험으로부터 보호하는 것은 인간의 본성뿐만 아니라 공통 시설을 자동화하고 체계화하는 것도 프로그래머의 본성입니다., 오류 검사, 메모리 진단, 로깅 프레임워크, 백업 유지 관리 등과 같은 것입니다.

프로그래머/인간은 왜 시스템에 공급하는 코드가 시스템에 해를 끼치지 않는지 확인하는 작업을 자동화하기 시작하지 않았습니까?물론이죠, 성능.하지만 이는 하드웨어 표준이 심각하게 침투하기 훨씬 이전의 일이었습니다."관리 코드"를 용이하게 하기 위해 마더보드가 버스 아키텍처와 추가 프로세서로 설계되지 않은 이유는 무엇입니까?

Model T Fords가 내가 놓칠 만큼 빠르지 않다는 비유가 있나요?

도움이 되었습니까?

해결책

이것을 첫 번째 원리부터 생각해 봅시다.

관리형 플랫폼은 고급 언어에서 생성된 프로그램 코드를 플랫폼에서 실행하기에 더 적합한 형식(IL 바이트코드)으로 실행할 수 있도록 상대적으로 샌드박스화된 영역을 제공합니다.가비지 수집 및 모듈 로딩과 같은 유틸리티 기능도 있습니다.

이제 기본 애플리케이션에 대해 생각해 보십시오. OS는 고급 언어에서 생성된 프로그램 코드를 플랫폼(x86 opcode)에서 실행하기에 더 적합한 형식으로 실행하기 위해 상대적으로 샌드박스된 영역(프로세스)을 제공합니다.가상 메모리 관리 및 모듈 로딩과 같은 유틸리티 기능도 있습니다.

큰 차이는 없지만, 애초에 플랫폼을 관리하는 이유는 단순히 플랫폼 코딩이 더 쉬워지기 때문이라고 생각합니다.OS 간에 코드를 이식할 수 있어야 하지만 MS는 이를 신경 쓰지 않았습니다.보안은 관리형 플랫폼의 일부이지만 OS의 일부여야 합니다.관리되는 앱은 일반 프로세스와 마찬가지로 파일 등을 작성할 수 있습니다.이를 제한하는 것은 보안 기능이며 네이티브에 존재하지 않는 관리형 플랫폼의 측면이 아닙니다.

궁극적으로 관리되는 모든 기능을 기본 dll 세트에 넣고 중간 바이트코드 아이디어를 폐기하고 대신 JIT를 기본 코드로 컴파일할 수도 있었습니다.GC와 같은 "관리형" 기능은 기본 힙에서 쉽게 가능합니다. 예를 보려면 Boehm C++ 항목을 참조하세요.

MS가 그렇게 한 이유는 부분적으로 컴파일러를 더 쉽게 작성할 수 있게 했기 때문이고 부분적으로는 Java가 만들어진 방식 때문이라고 생각합니다. (그리고 .NET은 정신적으로만 그렇더라도 Java의 후손입니다.) Java가 크로스를 만들기 위해 그렇게 한 것은 사실입니다. -플랫폼 코딩이 가능하지만 MS는 신경 쓰지 않는 것입니다.

그렇다면 처음부터 관리 코드를 얻지 못한 이유는 무엇입니까? '관리' 코드의 일부라고 언급한 모든 항목은 기본 코드이기 때문입니다.오늘날 우리가 보유하고 있는 관리형 플랫폼은 이미 추상화된 플랫폼 위에 추가된 추상화일 뿐입니다.고급 언어에는 자신을 보호하기 위해 더 많은 기능이 추가되었습니다. 버퍼 오버플로는 과거의 일이지만 C가 처음 발명되었을 때 C에서 구현하지 못했을 이유는 없습니다.단지 그렇지 않았을 뿐입니다.돌이켜보면 이러한 기능이 누락된 것처럼 보일 수도 있지만, 10년 후에는 "왜 C#에서는 오늘날처럼 분명히 유용한 XYZ 기능을 구현하지 않았습니까?"라고 묻게 될 것입니다.

다른 팁

보안 등이 내장된 관리 코드오랫동안 주변에 있었습니다.

원래 PC 플랫폼에는 이를 위한 공간이 없었고 나중에 추가되지도 않았습니다.

유서 깊은 IBM 메인프레임은 보호된 주소 지정, 손댈 수 없는 커널 라이브러리, 역할 기반 보안 등을 갖추고 있습니다.등.70년대부터.게다가 모든 어셈블러 코드는 정교한 (당시) 변경 관리 시스템으로 관리되었습니다.(Univac, Burroughs 등도 비슷한 것이 있었습니다.)

Unix는 처음부터 상당히 괜찮은 보안 기능을 내장하고 있었습니다(그리고 몇 년이 지나도 크게 변하지 않았습니다).

그래서 저는 이것이 Windows/웹 공간 문제와 매우 흡사하다고 생각합니다.

메인프레임 바이러스는 한번도 없었습니다!전 세계 대부분의 금융 거래는 어느 시점에서는 이러한 시스템을 통과하므로 매력적인 대상이 아닌 것 같습니다.

하지만 내부 IBM 메일 시스템은 최초의 '트로이 목마'를 호스팅했습니다!

실제로 관리 코드는 아주 오랫동안 사용되어 왔습니다.고려하다:

  • LISP
  • 잡담
  • BASIC (오리지널 맛)

메모리 및 기타 리소스 제어 문제로부터 사용을 보호하는 모든 운영 체제와 유사한 환경이 제공되었습니다.그리고 모두 상대적인 실패였습니다. (BASIC은 기본 시스템을 망칠 수 있는 PEEK & POKE와 같은 기능이 도입되었을 때만 실제로 성공했습니다.)

컴퓨터는 충분히 강력하지 않았고 이를 충분히 강력하게 만드는 데 너무 많은 비용이 들었습니다.사용할 수 있는 리소스가 제한되어 있으면 모든 바이트와 CPU 주기가 중요합니다.

제가 처음으로 사용한 컴퓨터는 싱클레어 ZX 스펙트럼 1982년에.현재 단일 Windows 글꼴 파일 크기보다 적은 RAM(16K)을 사용했습니다.그리고 그것은 비교적 최근의 가정용 컴퓨터 시대였습니다.1970년대 중반 이전에는 집에 컴퓨터를 두는 것은 상상도 할 수 없는 일이었습니다.

참고로 우리는 어셈블리를 직접 컴파일한 적이 없습니다.우리는 어셈블리 언어 코드를 손으로 조립했습니다.이제 그 점은 분명해졌습니다...

이런 의미에서 자동차의 속도는 컴퓨터의 속도와 유사하지 않기 때문에 귀하의 비유가 질문을 흐리게 하고 있습니다.자동차의 속도 증가는 자동차 안전의 변화를 필요로 했습니다. 그러나 컴퓨터 보안의 변화를 요구하는 것은 컴퓨터의 속도 증가가 아니라 연결성의 증가입니다.약간 다른 각도에서 보면:자동차의 경우 속도를 높이는 것이 운전 안전성을 높이는 기술.컴퓨터의 경우 속도를 높이는 것이 활성화 안전성을 높이는 기술.

그래서 최초의 자동차는 속도가 느렸기 때문에 사고가 발생해도 안전했습니다.최초의 컴퓨터는 네트워크로 연결되지 않았기 때문에 안전했습니다.

이제 안전벨트, 에어백, ABS, 충돌방지장치 등이 자동차를 더욱 안전하게 만들어줍니다.컴퓨터는 추가 기술을 통해 안전하게 만들어지지만 여전히 네트워크 케이블을 뽑는 것을 이길 수는 없습니다.

이것은 단순화된 내용이지만 핵심에 해당한다고 생각합니다.그 당시에는 컴퓨터가 네트워크에 연결되어 있지 않았기 때문에 그런 것이 필요하지 않았습니다.

300년 전에 기차가 없었던 이유도 마찬가지다.30년 전에는 휴대폰이 없었던 이유도 마찬가지다.우리에게 아직 순간이동 기계가 없는 이유도 마찬가지다.

기술은 시간이 지남에 따라 진화하는데 이를 진화라고 합니다.

그 당시에는 컴퓨터가 충분히 강력하지 않았습니다.백그라운드에서 가비지 수집기를 실행하면 애플리케이션 성능이 저하됩니다.

VM이 느린 하드웨어에서 실행될 수 없는 이유보다는 컴퓨터에 관리 코드 수준의 보호 메커니즘이 없는 이유에 대한 질문에 대해 설명합니다(이미 다른 게시물에서 설명함).짧은 대답은 그랬다는 것입니다.CPU는 잘못된 코드가 발생하면 시스템이 손상되지 않도록 예외를 발생시키도록 설계되었습니다.Windows에서는 이 문제를 잘 처리하지 못하지만 다른 OS도 있습니다.Unix는 시스템을 중단시키지 않고 프로그램이 종료되도록 이를 신호로 전달합니다.실제로 관리 코드를 실행 중인지 여부에 관계없이 널 포인터 예외는 프로그램 종료 시 동일한 방식으로 발생합니다.가상 메모리는 프로그램이 다른 코드를 망칠 수 없도록 보장하므로 프로그램이 할 수 있는 일은 스스로 해를 끼치는 것뿐입니다.

두 번째 요점으로 이동합니다.당신이 무엇을 하고 있는지 안다면 이 모든 것은 불필요합니다.가구를 깨끗하게 유지하고 싶다면 그 위에 음식을 떨어뜨리지 마세요.집을 비닐로 덮을 필요는 없고 조심만 하면 된다.당신이 엉성한 코더라면 세계 최고의 VM이 당신을 구해주지는 않을 것입니다. 단지 당신이 엉성한 코드를 아무런 소음 없이 실행할 수 있게 해줄 뿐입니다.또한 적절한 캡슐화를 사용하면 코드 포팅이 쉽습니다.당신이 좋은 코더라면, 관리되는 코드는 광범위하게 도움이 되지 않습니다.그렇기 때문에 모든 사람이 그것을 사용하는 것은 아닙니다.그것은 단순히 선호의 문제이지 더 좋다/나쁘다의 문제가 아닙니다.

런타임 보안에 관한 한 P 코드 컴파일러는 기계어 코드가 처리할 수 없다고 예측할 수 없으며, 관리 코드 인터프리터는 OS가 처리할 수 없는(또는 처리하지 않는) 작업을 처리할 수 없습니다.추가 버스, CPU 및 명령어 세트가 포함된 마더보드는 훨씬 더 많은 비용이 듭니다. IT는 비용/성능 비율이 가장 중요합니다.

1970년에는 메모리 가격이 약 $1/비트 (인플레이션 없이).그런 비용으로는 고급 쓰레기 수거를 감당할 수 없습니다.

대부분의 질문처럼 "Y년 전에 프로그래밍할 때 X가 없었던 이유"에 대한 대답은 속도/자원 할당이라고 생각합니다.제한된 자원으로 인해 최대한 효과적으로 관리해야 했습니다.관리 코드와 관련된 범용 관리 유형은 리소스를 너무 많이 소모하여 당시 성능이 중요한 응용 프로그램에 도움이 되지 않았습니다.이는 오늘날 성능이 중요한 코드가 여전히 C, Fortran 또는 어셈블러로 작성되는 이유 중 하나이기도 합니다.

왜 우리는 마차와 그 모든 지루한 것들을 가지고 놀지 않고 비행기와 우주선을 한꺼번에 만들었습니까?

중간 언어를 사용하려면 다음 두 가지 중 하나가 필요합니다.

  1. 상당한 성능 저하가 있는 런타임 해석(폭넓게 가변적 - 경우에 따라 2배 이하, 때로는 100배 이상)
  2. 추가 RAM이 필요하고 실행된 명령문 수보다는 프로그램 크기에 대략 비례하여 지연을 추가하는 JIT(Just-In-Time) 컴파일러

수년에 걸쳐 변경된 한 가지는 많은 프로그램이 모드에서 가장 많이 사용되는 부분을 예전보다 훨씬 더 많이 실행한다는 것입니다.특정 명령문이 처음 실행될 때 후속 실행보다 1,000배의 페널티가 발생한다고 가정합니다.각 명령문이 평균 100번 실행되는 프로그램에서 해당 페널티의 효과는 무엇입니까?각 명령문이 평균 1,000,000번 실행되는 프로그램에 해당 페널티가 미치는 영향은 무엇입니까?

JIT(Just-In-Time) 컴파일은 오랫동안 가능했지만 1980년대나 1990년대에는 성능 비용이 감당할 수 없을 정도였습니다.기술이 변화함에 따라 JIT 컴파일의 실제 비용은 완전히 실용적인 수준으로 낮아졌습니다.

대답은 더 명확해졌습니다. 인간은 프로그램을 작성하도록 만들어지지 않았습니다.기계가 그 일을 하고 우리가 팩맨을 하면서 긴장을 풀 수 있도록 해야 합니다.

그만한 가치가 있는지 알아보기 위해 나는 60년대와 70년대에 무엇보다도 이를 정확히 옹호하는 컴퓨팅 언어 수업(CAR Hoare의 논문과 Nicholas Wirth의 논문) 두어 편을 읽었습니다.

왜 이런 일들이 일어나지 않았는지 정확히 말할 수는 없지만, 당시에는 분명하지 않았지만 돌이켜 보면 분명해 보이는 일들 중 하나일 뿐이라고 추측합니다.이전 컴파일러가 보안에 대해 걱정하지 않았다는 것은 아닙니다.이를 수행하는 방법에 대해 서로 다른 생각이 있다는 것입니다.

Hoare는 "체크아웃 컴파일러"라는 아이디어를 언급합니다.내가 아는 한 이것은 본질적으로 정적 분석을 수행하는 컴파일러입니다.그에게 이것은 실패한 인기 있는 기술이었습니다(또는 적어도 해결하려고 했던 만큼 많은 문제를 해결하지 못했습니다).그에 대한 해결책은 관리 코드를 생성하여 프로그래밍 언어를 더욱 안전하게 만드는 것이었습니다(또는 적어도 현대 용어로 표현하면 그렇게 표현했을 것입니다).

일단 C(그리고 그 이후의 C++)가 인기를 얻으면 관리 코드에 대한 아이디어는 본질적으로 사라졌을 것입니다.C가 나쁜 언어라는 것이 아니라 응용 프로그래밍 언어가 아닌 어셈블리 언어로 의도되었다는 것입니다.

기회가 된다면 읽어보셔도 좋을 것 같아요 프로그래밍 언어 디자인에 대한 힌트.이런 종류의 일에 관심이 있다면 꽤 잘 읽어볼 수 있는 책입니다.

이 질문에 대한 가장 좋은 대답은 IMHO입니다. 당시에는 관리 코드에 대한 아이디어가 아무도 없었습니다.지식은 실제로 시간이 지남에 따라 진화합니다.건축이나 농업과 같은 분야에 비해 컴퓨터 과학은 매우 초기 단계입니다.따라서 해당 분야에 대한 집단적 지식도 젊고 시간이 지남에 따라 진화할 것입니다.아마도 몇 년 안에 우리는 새로운 현상을 접하게 될 것이며 누군가는 "왜 전에는 XYZ를 생각하지 않았나요?"라는 같은 질문을 하게 될 것입니다.

GC 및 관련 기술의 채택을 지연시키는 것은 가비지 수집의 비효율성에 대한 잘못된 인식과 결합된 변화 저항 때문이라고 말하고 싶습니다.물론 Intel 8086의 뇌사 세그먼트 메모리 모델은 PC에서 정상적인 메모리 관리를 촉진하는 데 정확히 도움이 되지 않았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top