Кіріспе
Компьютерлік жаргон. Компьютерде DLL Hell – Microsoft Windows операциялық жүйелерінде динамикалық байланыс кітапханаларымен (DLL) жұмыс істегенде туындайтын қиындықтарды білдіретін термин. Бұл әсіресе ескі 16 биттік нұсқаларда жиі кездеседі, олардың барлығы бір жад кеңістігінде жұмыс істейді. DLL Hell әртүрлі түрде көрініс беруі мүмкін, нәтижесінде бағдарламалар іске қосылмай немесе дұрыс жұмыс істемей қалуы мүмкін. DLL Hell – Windows жүйесіне тән, жалпы тәуелділік тозағының бір түрі.
In computing, DLL Hell is a term for the complications that arise when one works with dynamic link libraries (DLLs) used with Microsoft Windows operating systems, particularly legacy 16 bit editions, which all run in a single memory space. DLL Hell can manifest itself in many different ways wherein applications neither launch nor work correctly. DLL Hell is the Windows ecosystem specific form of the general concept dependency hell.
Қиындықтар
DLL – Microsoft-тың ортақ кітапханаларды іске асыруы. Ортақ кітапханалар жиі қолданылатын кодты бірге жинап, DLL түріндегі орамға салуға мүмкіндік береді, осы арқылы жүйедегі кез келген бағдарламалық қамтамасыз ету оны жадыға бірнеше көшірмесін жүктемей-ақ пайдалана алады. Мысалы, көптеген бағдарламаларда кеңінен қолданылатын GUI мәтін редакторын қарастырайық. Бұл кодты DLL-ге орналастыру арқылы жүйедегі барлық бағдарламалар оны қосымша жадты пайдаланбай қолдана алады. Бұл статикалық кітапханалармен қарама-қайшы, олар функционалды жағынан ұқсас, бірақ кодты тікелей бағдарламаға көшіреді. Осылайша, әрбір бағдарлама пайдаланатын кітапханалардың көлеміне сәйкес өседі, бұл қазіргі заманғы бағдарламалар үшін айтарлықтай үлкен болуы мүмкін. Мәселе компьютердегі DLL нұсқасы бағдарлама жасалған кезде қолданылған нұсқадан өзгеше болғанда туындайды. DLL-де кері үйлесімділік механизмі жоқ, тіпті DLL-ге енгізілген шағын өзгерістер де оның ішкі құрылымын бұрынғы нұсқалардан соншалықты ерекшелендіре алады, оларды пайдалануға тырысу бағдарламаның істен шығуына әкелуі мүмкін. Статикалық кітапханалар осы мәселені болдырмайды, өйткені бағдарламаны құру үшін қолданылған нұсқа оның ішінде сақталады, сондықтан жүйеде жаңа нұсқа болса да, бұл бағдарламаға әсер етпейді. Нұсқалардың үйлесімсіздігінің басты себебі – DLL файлының құрылымы. Файл DLL-де қамтылған жеке әдістердің (процедуралар, амалдар және т.б.) тізімін және олар қабылдайтын және қайтаратын деректердің түрлерін қамтиды. DLL кодына енгізілген шағын өзгерістер тізімнің қайта құрылуына әкелуі мүмкін, нәтижесінде каталогтағы төртінші элемент деп есептеп, белгілі бір әдісті шақыратын бағдарлама мүлдем басқа және үйлесімсіз амалға шақыруы мүмкін, бұл әдетте бағдарламаның істен шығуына себеп болады. DLL-мен байланысты көптеген мәселелер бар, әсіресе жүйеге көптеген бағдарламалар орнатылып, жойылғаннан кейін. Мұндай қиындықтарға DLL нұсқаларының қақтығысы, қажетті DLL-ді алудағы қиындықтар және қажетсіз DLL көшірмелерінің көп болуы жатады. Осы мәселелердің шешімдері Microsoft DLL жүйесін жасап жатқан кезде де белгілі болды. Олар NET платформасының "Assemblies" құрамына енгізілді.
Қосымша нұсқалар
Кітапхананың белгілі бір нұсқасы оны пайдаланатын кейбір бағдарламалармен үйлесімді, ал басқаларымен – үйлесімсіз болуы мүмкін. Windows жүйесі осыған байланысты әсіресе осал болды, себебі C++ кітапханаларын динамикалық байланыстыруға және Объектілерді байланыстыру мен ендіру (Object Linking and Embedding, OLE) объектілеріне ерекше мән берілді. C++ сыныптары көптеген әдістерді экспорттайды, ал сыныпқа енгізілген бір ғана өзгеріс, мысалы, жаңа виртуалды әдіс, оны бұрынғы нұсқаға сәйкес құрастырылған бағдарламалармен үйлесімсіз ете алады. Объектілерді байланыстыру мен ендірудің мұны болдырмау үшін қатаң ережелері бар: интерфейстер тұрақты болуы керек, ал жад менеджерлері ортақ болмайды. Дегенмен, бұл жеткіліксіз, өйткені сыныптың мағынасы өзгеріп қалуы мүмкін. Бір қолданбадағы қателерді түзету екінші қолданбадағы мүмкіндікті жоюға әкелуі мүмкін. Windows 2000-ге дейін Windows осыған бейім болды, себебі COM сыныптар тізімі барлық пайдаланушылар мен процестер арасында ортақ болды. Жүйеде нақты жалпы COM сынып идентификаторына (COM Class ID) ие болатын бір ғана COM объектісі бір DLL/EXE файлында жариялануы мүмкін еді. Егер қандай да бір бағдарлама сол сыныптың данасын (instance) жасауды қажет етсе, ол орталық тіркеудегі ағымдағы нұсқаны алатын еді. Нәтижесінде, ортақ объектінің жаңа нұсқасын орнататын бағдарлама бұрын орнатылған басқа бағдарламаларды күтпеген жерден бұзуы мүмкін.
DLL-ді аяусыз басу
Жаңа орнатылған бағдарлама жұмыс істейтін жүйелік DLL-ді бұрынғы, үйлесімсіз нұсқамен алмастырғанда жиі кездесетін және мазасыз мәселе туындайды. Осыған алғашқы мысал ретінде Windows 3.1 жүйесіндегі ctl3d.dll және ctl3dv2.dll кітапханаларын келтіруге болады: Microsoft үшінші тарап өндірушілерге өз бағдарламалық жасақтамаларымен бірге тарататын кітапханаларды жасады, бірақ әрқайсысы ең соңғы нұсқаның орнына өзі дамытқан нұсқаны таратты. DLL-ді қайта жазудың (stomping) себебі: Microsoft бұрын ортақ жүйелік компоненттер ретінде (бастапқыда C:\WINDOWS және C:\WINDOWS\SYSTEM) кодты тиімді бөлісу үшін, шектеулі RAM және дискілік кеңістігі бар ортақ жадты пайдаланатын жүйелерде DLL-ді таратты. Сөйтіп, үшінші тарап өндірушілер де осы әдісті қолданды. Бағдарламаларды орнатушылар әдетте DLL-ді жүйелік каталогтарға орнатуға және жаңа DLL-ді COM нысандары ретінде тіркеу үшін жүйелік тізілімді өңдеуге рұқсат беретін артықшылықты қауіпсіздік контекстінде іске қосылады. Осылайша, нашар жазылған немесе дұрыс конфигурацияланбаған орнатушы Windows Файлдарды қорғау немесе Windows Ресурстарын қорғау өзгерісті кері қайтара алмайтын Windows-тың ескі нұсқаларында жүйелік кітапхананы төмендетуі мүмкін. Windows Vista және одан кейінгі нұсқаларда тек «сенімді орнатушы» тіркелгісі ғана негізгі операциялық жүйе кітапханаларына өзгерістер енгізе алады. Windows бағдарламаларына өздерінің орнату бағдарламаларына операциялық жүйе жаңартуларын қосуға рұқсат берілді. Яғни, көптеген Microsoft DLL-дері қайта таратылатын болып табылады, яғни бағдарламаларға белгілі бір кітапханалардың қызметтері қажет болса, оларды қосуға болады. Windows Installer пайда болғанға дейін Windows орнатушылары тарихи тұрғыдан коммерциялық өнімдер болып келді; көптеген адамдар өздерінің орнатушыларын жасауға тырысты, бірақ осы процесте нұсқаларды басқару мәселелерін елемеді немесе дұрыс шешпеді. Кейбір даму орталары жинақталған кітапханаларына автоматты түрде нұсқа ресурсын қоспады, сондықтан көптеген әзірлеушілер бұл мәселеге назар аудармады. Файлдың күнін тексеру, бар файлдарды жаңа нұсқамен алмастыру немесе DLL орнатылған болса, көшіру операциясын өткізіп жіберу дұрыс нұсқалаудың орнына қол жетімді жалғыз нұсқалар болып табылды. Кейде операциялық жүйе өзі DLL файлдарын ескі немесе қолданыстан шыққан нұсқалармен алмастырды. Мысалы, Windows 2000 түсті принтерден кейін қара-ақ принтер орнатылса, түс сезетін DLL-дердің үстіне қара-ақ принтер DLL-дерін орнататын.
Microsoft in the past distributed runtime DLLs as shared system components (originally C:\WINDOWS and C:\WINDOWS\SYSTEM), as a way of efficiently sharing code in a shared memory OS with limited RAM and disk space. Consequently, third party developers also distributed these in such a manner. Application installers are typically executed in a privileged security context that has access to install DLLs into the system directories and to edit the system registry to register new DLLs as COM objects. A poorly written or misconfigured installer can therefore downgrade a system library on legacy versions of Windows, on which Windows File Protection or Windows Resource Protection does not roll back the change. On Windows Vista and later, only the "trusted installer" account can make changes to core operating system libraries. Windows applications were permitted to include OS updates in their own installation programs. That is, many Microsoft DLLs are redistributable, meaning that the applications can include them if they need the services of the particular libraries. Before Windows Installer, Windows installers historically were commercial products; many people attempted to write their own installers, overlooking or mishandling versioning problems in the process. Some development environments did not automatically add a version resource in their compiled libraries, so many developers overlooked this aspect. Checking file dates, overwriting existing files or skipping the copy operation if the DLL was already installed were the only options available instead of correct versioning. Sometimes, the OS itself removed or replaced DLLs with older or obsolete versions. For example, Windows 2000 would install black and white printer DLLs on top of color aware DLLs, if a black and white printer was installed after the color printer.
Дұрыс емес КОМ тіркеу
COM және Windows-тың басқа бөліктерінде, қатар тіркелімсіз жинақтар енгізілгенге дейін, қолданылатын негізгі DLL-ді анықтау үшін тіркелім пайдаланылды. Егер модульдің басқа нұсқасы тіркелген болса, күтілген нұсқаның орнына осы DLL жүктелер еді. Мұндай жағдай бір кітапхананың әртүрлі нұсқаларын тіркейтін келіспеушілік орнатулардың нәтижесі болуы мүмкін, онда соңғы орнатылған нұсқа басымдыққа ие болар еді.
Ортақ жады модульдері
Windows-тың 16 биттік нұсқалары (және Windows ішінде Windows) кез келген DLL-дің тек бір данасын ғана жүктейді; барлық қолданбалар оны жадыдан шығарылғанға дейін жадыдағы бірдей көшірмеге сілтеме жасайды. (Windows-тың 32 биттік және 64 биттік нұсқаларында процестер арасындағы ортақ пайдалану тек әртүрлі атқарылатын файлдар бірдей каталогтан модульді жүктеген кезде ғана болады; код, бірақ стек емес, "жад бейнелеу" деп аталатын процесс арқылы процестер арасында бөліседі.) Сондықтан, тіпті қажетті DLL жүйелік каталог немесе қолданбалық каталог сияқты оны табуға болатын каталогта орналасқан болса да, егер басқа қолданба үшінші каталогтан үйлесімсіз нұсқамен іске қосылса, ешқайсысы қолданылмайды. Бұл мәселе 16 биттік қолданба қатесі ретінде көрінеді, ол тек қолданбалар белгілі бір ретпен іске қосылғанда ғана пайда болады.
Қызметке жарамдылықтың болмауы
DLL-ді басып тастау мәселесімен тікелей қарама-қарсылықта: Егер DLL-ге жасалған жаңартулар оны пайдаланатын барлық бағдарламаларға әсер етпесе, онда DLL-ге "қызмет көрсету" – яғни DLL-дің қолданыстағы нұсқаларындағы мәселелерді жою – әлдеқайда қиындап кетеді. (Қауіпсіздік түзетулері бұл жағдайды ерекше қынжырлы және маңызды етеді.) DLL-дің ең соңғы нұсқасын ғана түзетудің орнына, жасаушы идеалды жағдайда түзетулерін жасап, DLL-дің шығарылған әрбір нұсқасымен үйлесімділігін тексеруі тиіс.
Жәндіктерді пайдалану
Windows операциялық жүйесінде толыққанды атауы көрсетілмеген DLL-дерді жүктеудегі беймаздық соңғы жылдары түрлі зиянды бағдарламалар тарапынан пайдаланылып, көптеген әртүрлі бағдарламалық жасақтама жеткізушілердің, сондай-ақ Windows-тың өзіне қатысты жаңа түрдегі осалдықтарды тудырды.
Шешімдер
Жылдар бойы DLL тозағының әртүрлі формалары шешілді немесе азайтылды.
Статикалық байланысу
Қолданбадағы DLL Hell мәселесін шешудің қарапайым жолы – барлық кітапханаларды статикалық байланысқа салу, яғни, белгілі бір атаумен жүйелік кітапхананы таңдаудың орнына, бағдарламаға қажетті кітапхана нұсқасын қосу. Windows 2000 жүйесінде енгізілген бұл тәсіл, әрбір қолданбаға қажетті DLL-дің жеке-жеке көшірмелерін жүктейді (соның арқасында, қақтығысқа түсетін DLL-ді қажет ететін қолданбаларды бір уақытта іске қосуға болады). Бұл әдіс қақтығыстарды болдырмауға мүмкіндік береді, себебі қолданбаларға модульдің бірегей нұсқаларын өздерінің жад кеңістігіне жүктеуге рұқсат береді, сонымен қатар DLL-ді қолданбалар арасында бөлісудің басты артықшылығын сақтайды (яғни, жадты үнемдеуге мүмкіндік береді), өйткені жадты бейнелеу техникаларын қолдану арқылы әлі де бірдей модульді пайдаланатын әртүрлі процестер арасында ортақ кодты бөліседі. Алайда, бірнеше процесте ортақ деректерді пайдаланатын DLL-дер бұл тәсілді қолдана алмайды. Бір кемшілігі – DLL-дің қаңғыбақ көшірмелері автоматтандырылған процестер кезінде жаңартылмауы мүмкін.
Портативті қолданбалар
Қолданба архитектурасы мен орындалу ортасына байланысты, портативті қолданбалар кейбір DLL проблемаларын азайтудың тиімді жолы болуы мүмкін, себебі әрбір бағдарлама өзіне қажетті DLL-дердің жеке көшірмелерін қосады. Бірақ, икемділіктің артуы қауіпсіздікке қатысты салдарға алып келуі мүмкін, егер жеке DLL-дер ортақ DLL-дер сияқты қауіпсіздік түзетулерімен үнемі жаңартылмайтын болса. Сонымен қатар, қолданбаларды виртуализациялау бағдарламаларды "қорғалған ортада" іске қосуға мүмкіндік береді, бұл DLL файлдарын тікелей операциялық жүйеге орнату қажеттілігін жояды.