dll

dll의 지옥

sungtg 2008. 2. 4. 14:06

DLL 지옥(영어: DLL hell)
마이크로소프트 윈도 기반의 프로그램에서 DLL을 사용할 경우 발생할 수 있는 복잡성을 뜻하는 말이다. 이 용어는 릭 엔더슨(Rick Anderson)이 2000년 1월에 발표한 〈DLL 지옥의 종말(The End of DLL Hell)〉 이라는 문서를 통해 대중에 소개되었다.
그 전에는 잠시 동안 마이크로소프트 내부에서 사용됐었다.

DLL 지옥은 DLL을 관리할 때 발생할 수 있는 모든 문제를 뜻한다.
여기에는 DLL 버전 충돌 문제, 프로그램이 의존하는 DLL 파일을 찾을 때의 어려움,
불필요한 DLL 파일 복사본이 만들어지는 문제 등이 포함된다.

DLL 지옥은 잠재적인 운영 체제 설계 결함의 한 예이다.
이 결함으로 인해 잘 작성된 프로그램도 문제를 일으킬 수 있는데,
이는 허술하게 작성된 프로그램의 나쁜 프로그래밍 습관이나 버그로부터 영향을 받을 수 있고,
이를 운영체제가 묵인하기 때문이다.

문제점

DLL을 사용하다 보면 많은 문제들에 마주치게 되는데,
이는 특히 시스템에 많은 프로그램을 설치한 후 제거한 상황이라면 더욱 두드러진다.
이중 가장 일반적이면서도 까다로웠던 문제는 시스템 DLL이 다른 버전의 DLL로 덮어 써져서,
일부 애플리케이션이 동작하지 않게 되는 경우였다.
마이크로소프트에서 'DLL 스탐핑(DLL Stomping)'이라고도 부르는 이러한 DLL 덮어쓰기 문제는 [[마이크로소프트 윈도의 역사|윈도 2000]]을 통해 소개된
윈도우 파일 보호(Windows File Protection, WFP)(http://www.microsoft.com/whdc/winlogo/drvsign/wfp.mspx) 기능을 통해
대부분 해결되었다.
WFP이 있기 전에는 다음과 같은 원인들 때문에 DLL 호환 관련 문제가 발생했었다

* 의무적인 표준 DLL 버전 관리 방식과 이름 짓기, 파일 시스템 위치 스키마가 없었다는 점.
* 의무적인 표준 소프트웨어 설치 방법이 없었다는 점

* DLL [애플리케이션 이진 인터페이스] 관리를 위한 중앙 집중적인 권위 있는 지원이 없었다는 점.
* 파일 이름이 같은 서로 호환되지 않는 DLL들을 허용할 수 있는 안전 장치가 없었다는 점.

* 배포되는 버전 구별을 위한 내부 버전 번호가 없었다는 점.
* 사용자가 의심스러운 DLL을 복사하거나, 기존의 DLL을 변경하는 것을 예방하는 간단한 관리 도구조차 없었다는 점.

DLL 호환 문제 해결을 위한 '병렬식 컴포넌트 공유(Side-by-Side Component Sharing)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsetup/html/sidebyside.asp
같은 일부 예방 기법은 DLL의 복사본을 만들고,
각 버전의 DLL들이 필요에 따라
따로 메모리로 올려지도록 하기 때문에,
DLL 공유에 따른 메모리 절약 효과가 감소하게 된다.
또한 버그 수정과 보안 업데이트 시에도 복잡성 증가 등의 영향을 받게 된다.

대응 수단

DLL 지옥을 피하는 데에는 여러 방법이 알려져 있으며, 이들 모두를 동시에 사용하면 최적의 효과를 얻을 수 있다

* '''레지스트레이션-프리 COM''': [[윈도 XP]]는
'레지스트레이션-프리 COM(Registration-free COM, 등록이 필요없는 COM)'이라 불리는 새로운 [[컴포넌트 오브젝트 모델|COM]] 오브젝트 등록 모드를 소개하였다.
이 기능은 [[닷넷 프레임워크|닷넷]]의 발표와 맞물려 소개되었기 때문에 그리 잘 광고되지는 않았다.

레지스트레이션-프리 COM은 애플리케이션이 COM 오브젝트들을 설치할 때 COM 등록에 필요한 정보를 전역적인 [[윈도 레지스트리|레지스트리]]가 아닌 자신의 디렉터리에 저장하여 사용할 수 있도록 한다.
엄밀히 말해 이 기능은 해당 COM 컴포넌트들을 단일 애플리케이션에서 사용할 경우에만 적용이 가능하다.
이 기능을 통해 각 애플리케이션은 자신에게 필요한 버전의 COM DLL을 설치하여 사용할 수 있는데,
이 결과로 시스템에는 특정 DLL에 대한 다양한 버전의 DLL 파일들이 존재하게 된다.

(마이크로소프트에서는
이를 '병렬식 어셈블리(Side-by-side Assemblies)'[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sbscs/setup/side_by_side_assemblies.asp] 라 부른다.)

레지스트레이션-프리 COM 을 사용하면 대부분 DLL 지옥을 피할 수 있다.
다만 최소 윈도 XP 또는 그 이상의 상위 버전의 OS가 필요하며, EXE COM 서버 및 시스템 전역적인 컴포넌트들 즉 MDAC, MSXML, [[다이렉트엑스|다이렉트X]] 및 [[인터넷 익스플로러]] 등에는 사용할 수 없다.

* DLL 파일들의 의존성을 추적 및 관리할 수 있는 [[패키지 관리 시스템]]을 운영 체제에 포함하여, 사용자에게 패키지 관리 시스템의 사용을 장려하고, 수동으로 DLL 파일을 설치하지 말 것을 권고한다.

* 라이브러리 배포에 대한 사항을 중앙에서 집중 관리할 수 있는 시스템을 마련하고,
라이브러리를 변경하려면 이 시스템을 통하도록 한다 이를 통해, 여러 버전의 소프트웨어에 대해서도 서로 호환성이 유지되도록 할 수 있다.
예를 들어 만약 특정 하위 버전의 소프트웨어가 현재의 라이브러리와 서로 호환되지 않는다면, 그 소프트웨어를 위해 시스템은 호환 가능한 인터페이스를 제공하거나, 적절히 격리된 형태로 해당 소프트웨어가 요구하는 버전의 패키지를 공급하도록 할 수 있다.

* 만약 소프트웨어 개발에서 라이브러리의 수정이 불가피하다면, 이 라이브러리의 DLL을 프로그램의 개인적인 공간 즉 프로그램 디렉터리 같은 곳에 두거나, 라이브러리를 프로그램에 정적으로 링크하여 [[컴파일러|컴파일]]하도록 한다.

* 적절한 소프트웨어 디자인 방법을 따른다. DLL은 시스템의 구성 요소들을 모듈화하여 별개의 라이브러리로 만드는 훌륭한 방법이다; 그러나 모든 경우에서 항상 사용해야 하는 것은 아니다.

예를 들어 만약 프로그램이 다른 어느 곳에서도 사용되지 않는 라이브러리를 필요로 한다면, 이를 정적으로 링크하여 용량 증가 등의 특별한 불이익 없이 실행 속도를 향상시킬 수 있다.