Pull to refresh

Comments 52

Это совсем другая история. Работает механизм DLL здесь правильно и прозрачно, а проблема в том, что CRT кэширует у себя окружение, от этого вся беда.

Как-то читал обсуждение проблемы передачи FILE* между модулями — это тоже может быть недопустимо по причине разных CRT. Об этом надо помнить и учитывать. Тот кто с этим столкнулся привык к ситуации linux-ов, где libc все время одинаковая грузится. Кстати очень интересно, можно ли добиться подгрузки разных libc в разных .so библиотеках? Мне кажется нет.
Ну тривиальным образом можно зачрутить и тогда libc может быть какая угодно. Нетривиально — перекомпилить с другим путём к ld-linux.so.
Т.е. и в Linux может возникать проблема с разными библиотеками? К примеру сторонняя библиотека давно не менялась и зависит от одной версии libc, а разрабатываемая уже от другой. Или такое на практике пресекается и никто это не поддерживает?
Концептуально, наверное, можно. На практике для этого потребуются десятилетия. Мы весной вывели из эксплуатации одну системку на RedHat EL 4, так даже там libc была бинарно-совместима с более новыми версиями из RedHat EL 5, SUSE и.т.д. (а вот версия библиотеки С++ — libstdc++ сменилась, так как в RH4 был GCC 3, а в более новых — 4.*). Возможно, я ошибаюсь, но лично я не видел реальных приложений, ситуаций, где такая проблема могла бы возникнуть в Linux.

Проблема dll-hell в Windows, в данном случае, из-за того, что в C-рантайме от MSVC с бинарной совместимостью все очень печально. Правильнее сказать, что между двумя версиями рантайма ее нет вообще. Из-за этого различные exe и dll приходиться линьковать с msvcrt строго определенной версии, так как другие версии просто будут иметь другой ABI.

А такие проблемы с ABI, в одной из основных библиотек Windows, возникают из-за того, что MS никак не может решиться просто реализовать libc и libstdc++ по соответствующим стандартам языков, а все время придумывают свои расширения, объявляют функции устаревшими, включают отладочные проверки в релиз-версиях (при этом отключение этих проверок ломает ABI даже в пределах версии crt) и производят другие действия с аналогично-непонятным смыслом.

Я сейчас тоже вплотную столкнулся с проблемами из-за подобной политики MS, но в моем случае оказалось возможно просто перекомпилировать все зависимые библиотеки со строго одинаковым набором опций компилятора. Но это на текущий момент закрытая разработка, поэтому мы можем позволить себе такие вольности. В открытом или тиражируемом продукте такой подход, скорее всего, будет непозволительной роскошью.
В windows они оставили за собой право менять версии библиотек и при этом не сохранять бинарную совместимость и я считаю, что это верно, иначе никакого развития библиотеки не получилось бы. Одна из сторон DLL hell как раз состоит в том, что иногда пытались подменить одну библиотеку на другую якобы сохраняя совместимость. На практике это очень и очень сложно, т.к. код может быть завязан даже на ошибки, которые после исправления приведут к проблемам. Короче говоря должно быть четкое версионирование, это было сразу заложено в имени библиотеки, но это и другая культура разработки, надо понимать, что каждый модуль имеет свою CRT и надо думать об аллокаторах, не использовать FILE* и пр.

С другой стороны DLL hell забороли тотальным версионированием, которое уже давно работает для DLL. Рекомендуется private развертывание, когда копируется все в папку с кодом, остальное работает через winsxs куда попадает куча разных вариантов зарегистрированных библиотек.

Кстати механизм форсированной подмены есть и в winsxs и наверное его иногда применяют.
Возможно, но почему тогда в Linux библиотеки (libc, libstdc++) развиваются, а ABI остается стабильным и обратно совместимым на протяжении многих лет? А то, что делает Microsoft скорее напоминает деградацию. Как минимум деградацию производительности.

К сожалению, эта не другая культура разработки. Это бардак разработки. Культура разработки — это когда все взаимодействия зафиксированы на уровне различного рода договоренностей (таких как API, ABI и т.д.). В случае Windows такие договоренности отсутствуют даже в пределах одной программы.
К тому же для С-библиотек сохранять ABI не так сложно. Для С++ сложнее, но для STL-библиотеки не на много.

надо понимать, что каждый модуль имеет свою CRT и надо думать об аллокаторах, не использовать FILE* и пр.

Это было бы можно понять, если бы речь шла о какой-либо собственной разработке Microsoft, но когда речь идет о стандартизированных языках, то очень странно, что даже в пределах одной программы полноценно использовать возможности языка просто опасно.
Есть такой факт — очень сложно обновлять библиотеку в бинарном виде, сохраняя ее API и при этом не вызвать проблем. Даже исправление ошибки может привести к проблеме в пользовательском коде. Поэтому, то что делают с libc — это нечто героическое. Я слышал на эту тему историю с приложениями под meego — был апдейт qt библиотек, который привел к проблемам с частью софта. Идея была та-же — мы ничего не меняли, а только улучшили, не меняя версию. Вот это пример таких граблей. Конечно libc меняют реже и очень тщательно вылизывают, но гарантий все равно нет. Надежный способ — это версионирование, так поступают и в managed языках, компоненты четко версионируются, включая базовые библиотеки.

Теперь о культуре. Есть API и он реализуется библиотекой, это первое, второе — авторы сразу сказали, что версии будут меняться, при этом максимально сохраняя преемственость. Тут все ясно и понятно, такой путь реализуют большинство разработчиков компонент.

Про стандарты тут спорить не буду. Microsoft развязал себе руки, сделал так как им удобнее и гибче, плюс политические мотивы. Но надо сказать, что в мире UNIX наличие стандартов не решает всех проблем, портирование все равно является головной болью.
Деградация производительности CRT — это откуда такие сведения?
Я несколько неточно выразился. Я имел ввиду библиотеку STL, которую в случае MSVC можно отнести к CRT, да и вроде-бы даже часть кода рантайма С++ находится именно там.

Начиная с MSVC 2005 в STL добавляли различный отладочный функционал (включается/отключается дефайнами _SECURE_SCL, _HAS_ITERATOR_DEBUGGING, _ITERATOR_DEBUG_LEVEL). Я согласен, что этот функционал хорош при отладке, НО он по умолчанию включен в релиз-сборках! Это было-бы не так плохо, если бы включение/выключение этих опций не ломало ABI, но так как ABI ломается, то требуется чтобы во всем проекте эти опции были установлены одинаково.

Выключение этих опций в моем случае давало прирост производительности примерно в 2 раза, что не мало. Вот еще одно мнение по поводу этих опций blogs.warwick.ac.uk/ahazelden/entry/visual_studio_stl/. По сути оно совпадает с моим.
Да, я в курсе этих экспериментов с итераторами, мы вообще стараемся минимизировать использование STL. _SECURE_SCL=0 с самого начала везде поставили. Тут они пожертвовали производительностью в угоду безопасности. Согласен — делать по умолчанию это было нехорошо.
А то, что делает Microsoft скорее напоминает деградацию. Как минимум деградацию производительности.

Деградацией является динамической линковка, особенно динамическая линковка CRT.
Деградацией является динамической линковка, особенно динамическая линковка CRT.

Почему?
Например, зачем мне в каждый exe-файл проекта статически линьковать по 20-30Мбайт библиотек, если их можно сделать динамическими и тем самым получить дополнительные преимущества, такие как возможность централизованного обновления, отсутствие дублей кода библиотек в памяти и т.д.

Возможно, я чего-то не понимаю в экосистеме Windows, но мне, как разработчику, который пришел из мира Linux, такие подходы к разработке, отсутствие совместимости ABI и отсутствие простого способа указать пути поиска тех же библиотек (RPATH, LD_LIBRARY_PATH) кажутся дикими.
такие как возможность централизованного обновления
Не бывает обновления DLL без обновления EXE. Только в ооооочень редких случаях, и всё равно чревато. А раз EXE там же где и DLL — нет смысла её шарить и отказываться от IPO.

отсутствие дублей кода библиотек в памяти
Было актуально во времена 286/386. По легенде оттуда же __stdcall пошёл, чтобы на объёме байткода сэкономить. Сегодня это всё неактуально.

отсутствие совместимости ABI
Совместимость ABI есть, просто не надо пользоваться зоопарком компиляторов. Для Win есть MSVC, всё остальное — от лешего.
P.S: и 20-30 мегабайт при статической линковке не будет, т.к. слинкуется только то, что реально используется.
Не бывает обновления DLL без обновления EXE.

Бывает. Достаточно посмотреть на любой Linux. В Windows из-за отсутствия совместимого ABI системных библиотек с этим сложнее.

Совместимость ABI есть, просто не надо пользоваться зоопарком компиляторов. Для Win есть MSVC, всё остальное — от лешего.

В том-то и проблема, что в MSVC совместимого ABI нет. CRT из VC 10 нельзя подсунуть вместо CRT из VC 9. Да и с совместимостью STL проблемы есть.
Бывает. Достаточно посмотреть на любой Linux. В Windows из-за отсутствия совместимого ABI системных библиотек с этим сложнее.

Зато проще с установкой софта — не приходится половину библиотек апдейтить на нужные версии, собирая часть их них на коленке, когда в публичном репозитарии оказывается слишком старая версия dependency.

В том-то и проблема, что в MSVC совместимого ABI нет. CRT из VC 10 нельзя подсунуть вместо CRT из VC 9. Да и с совместимостью STL проблемы есть.

CRT — не простая DLL, чтобы к ней применять термин ABI (собс-но поэтому мне и кажется странным её вынос в DLL по умолчанию — не так уж она много весит, и жервтование IPO на CRT в угоду DLL выглядит сомнительным). Для остальных DLL/OBJ/LIB ABI есть, по крайней мере между разными версиями MSVC.

Да и с совместимостью STL проблемы есть.
STL — дело комилятора, а не линковкщика.

По большому счёту, динамическая линковка — это эстетство в угоду практичности.
Чем проще? Тем что каждый exe тянет за собой over 9000 разный DLL забивая диск и память? Это не практичность, а глупость какая-то. Конечно можно заставить пользователя покупать новый компьютер каждый 2-3 года, но вот что делать с embedded системами, где память и процессор ограничены?

Если работать в рамках дистрибутива, то никаких проблем с библиотеками не будет, так как они все будут совместимы, если нет, и нужно что-то очень экзотическое и новое, тогда gentoo вам в помощь, соберете каким угодно компилятором с какими угодно зависимостями.
Чем проще? Тем что каждый exe тянет за собой over 9000 разный DLL забивая диск и память? Это не практичность, а глупость какая-то.
Я о том же. Каждый exe тянет только себя, хоть и весит под 10Mb. Статически слинкованный с необходимыми частями своих библиотек.

но вот что делать с embedded системами, где память и процессор ограничены?
Использовать ограниченную OS :)
Ну вот вы написали foo.exe, я написал bar.exe, а Вася написал baz.exe и все мы используем функции из quz.dll, то все её тянут за собой что ли? Ещё и все разных версий.

>>Использовать ограниченную OS :)

Ну вообще-то ещё в 70ых поняли, что надо бы отдать железо операционке, а программисту оставить системные вызовы, чтобы он вообще не думал на каком железе он свою программу запускает.
Ну вот вы написали foo.exe, я написал bar.exe, а Вася написал baz.exe и все мы используем функции из quz.dll, то все её тянут за собой что ли? Ещё и все разных версий.

Все тянут за собой части quz.lib нужной версии в своём статически слинкованном теле exe'шника.

Ну вообще-то ещё в 70ых поняли, что надо бы отдать железо операционке, а программисту оставить системные вызовы, чтобы он вообще не думал на каком железе он свою программу запускает.

Речь не о kernel-mode, где динамическая линковка — вынужденная мера для изоляции, а о user-mode dll, где актуальность динамической линковки осталась в тех же 70ых (вместе с философией unix'ов).
>Все тянут за собой части quz.lib нужной версии в своём статически слинкованном теле exe'шника.

то есть в каждом есть своя fopen(), например, если все её юзают? Зачем тогда операционка вообще. Вкомпилить всё в один exe и как livecd распространять. Зато никаких глюков.

Вот я и думаю, почему дрова для HP принтера под винду занимают 500 метров, а под linux 500кб. Ну хотя там есть инсталлер с картинкой улыбающихся тётек и дядек, видать на философией unix смеются ;)
то есть в каждом есть своя fopen(), например, если все её юзают? Зачем тогда операционка вообще.

Для наименее инвазивного взаимодействия этих exe.

Вот я и думаю, почему дрова для HP принтера под винду занимают 500 метров, а под linux 500кб.

Думаю потому что их пишут любители компонетного программирования, таскающие Qt для about box'а (garbage collector coding style).
>Для наименее инвазивного взаимодействия этих exe.

Тогда можно и ядро запускать отдельное для каждой программы на вирутальном оборудовании. Вообще никакого взаимодействия.

> таскающие Qt для about box'а
А зачем таскать fopen, если они уже в системе есть?
Тогда можно и ядро запускать отдельное для каждой программы на вирутальном оборудовании. Вообще никакого взаимодействия.

По сути так оно и работает (virtual address space), когда exe не хотят друг с другом контачить.

А зачем таскать fopen, если они уже в системе есть?
Затем что своё подконтрольней. Всякие хуки, размеры буферов, IPO в конце концов. А при relocate base address от copy-on-write всё равно никуда не денетесь — память как ело, так и будет есть под разные копии.
Зато проще с установкой софта — не приходится половину библиотек апдейтить на нужные версии, собирая часть их них на коленке, когда в публичном репозитарии оказывается слишком старая версия dependency.

Возможно, у нас с Вами разный опыт, но в своей жизни, как пользователя, я с таким не сталкивался. Все конфликты разруливали мэйнтейнеры репозиториев и я получал уже работающие пакеты.
Как программисту, мне приходилось собирать свои пакеты с другими версиями библиотек, но это приходилось делать только если была необходимость пропатчить библиотеку какими-либо специфичными для проекта патчами.

CRT — не простая DLL, чтобы к ней применять термин ABI

Правильно! CRT — это такая библиотека, экспортируемые функции которой строго стандартизированы международными стандартами С/С++. Вот именно по этому CRT и должна иметь фиксированный интерфейс, как на уровне API, так и на уровне ABI для стандартизированных функций. И уж тем более не допустима такая самодеятельность, как отсутствие обратной совместимости, из-за чего возможна абсурдная ситуация, при которой одно приложение использует несколько несовместимых между собой CRT.

STL — дело комилятора, а не линковкщика.

И линковщика. Не вся STL помещается в шаблонах и заголовочных файлах. Часть ее вкомпилирована в CRT.
Все конфликты разруливали мэйнтейнеры репозиториев и я получал уже работающие пакеты.

В репозиториях часто бывают доступны только слишком старые версии.

CRT — это такая библиотека, экспортируемые функции которой строго стандартизированы международными стандартами С/С++.
CRT — это библиотека с точки зрения языка C/C++, но не библиотека с точки зрения ОС (т.е. не полностью независимый файл). CRT — это часть компилятора, часть его кодогенератора если хотите. Захочет компилятор инлайнить fopen() в каждой строчке — флаг ему в руки. Реализация CRT в виде .lib, .dll, .obj или еще какого-то os-library-одобного способа — всего лишь вариант реализации этого аспекта C/C++.

И линковщика. Не вся STL помещается в шаблонах и заголовочных файлах. Часть ее вкомпилирована в CRT.

STL вообще не обязана быть модулем. Вы знаете, почему сделали #include , а не #include <list.h>? Потому что даже хедер-файл с именем list существовать не обязан. В общем виде эта директива делает видимым в коде std::list, и больше ничего она делать не обязана. Реализация этого поведения #include через чтение файла с именем 'list', в котором что-то написано на языке C++ — всего лишь способ реализации, но по сути (по стандарту) STL — это часть парзера/кодогенератора компилятора, и ни в какие .h/.lib/.dll файлы она отображаться не обязана, это всего лишь простейшая её реализация.
(парзер съел местами #include <list>)
А можно было попробовать GetEnvironmentVariable()/GetEnvironmentStrings(). Да, проблемы с переносимостью, но есть и плюсы.
Это не поможет, т.к. сторонняя библиотека использует crt-шные ф-ии, следовательно читать она будет не из реального окружения, а из копии. А putenv в реальное окружение тоже пишет, иначе бы не работал старый вариант, да и пришлось бы при старте процесса им как-то специально сбрасывать окружение из кэша в систему.
Да, сильно. Я вначале подумал, что библиотека именно Ваша. В таком случае (да и вообще) идеологически верно запускать дочерний процесс с нужным окружением.

Правда тут ещё в голову пришла шальная мыслишка: явно загрузить msvcrt8 и вызвать её putenv(), до вызова library.foo(). Но это так, из области извращений. =)
Я просматривал разделы «программирование», там разве что «visual studio» подходит, но уклон там все-же иной. Здесь же речь идет о стандартной библиотеке C/C++ со спецификой windows, пошел в раздел языки, там есть «c++».
Да, пожалуй это верно, перенес.
>>Узнав это вспоминаем, что сторонняя библиотека использует msvcrt8, а мы msvcrt10.
с другой стороны
>>наш процесс неявно грузит msvcrt10
>>logitech неявно за собой тянет msvcrt8, инициализирует свою копию окружения
>>мы меняем окружение msvcrt9.putenv(VAR=str)

Так у вас три версии используется (8,9,10)? Или тут где-то одна лишняя.

Я там опечатался, исправлю. Речь идет о двух версиях exe зависит от 10, dll от 8.
Интересная грабля. Кстати, если цель исключительно в том, чтобы установить переменную окружения для library.dll, то можно ручками позвать msvcrt8.putenv если я правильно понимаю. Хотя устанавливать окружение до старта процесса это, конечно, правильнее.
Можно конечно, но это уже слишком изощренно. К тому-же та библиотека тоже обновляется и они могут вдруг перейти на другую версию CRT. Проще и правильнее все установить в родителе.
Не, изощренно это было бы detours'ом повесить хук на GetEnvironmentVariable ;)
Если есть возможность установить в родителе, то конечно так лучше. Мне не очень понятно почему вы изначально так не сделали, а стали «изнутри» переменные пытаться устанавливать.
Этот процесс уже был отдельным (был и родитель) и служил только одной цели — выполнить некое сложное действие с использованием сторонней библиотеки. Дело в том, что настройка окружения этой библиотеки дело не очень простое, там десяток переменных и ряд других настроек, поэтому все было в этот модуль помещено. Родитель не знает специфику и там эти настройки архитектурно делать неверно. Сделать их один раз перманентно и сохранить тоже нельзя, т.к. раз от раза могут меняться параметры.

В итоге сделали так — этот процесс в начале конфигурируется потом запускает второй экземпляр самого себя и уже в нужном окружении делает загрузку библиотеки и остальные шаги.
Второй экземпляр самого себя тоже не выглядит архитектурно верно…
Я бы сделал «некое сложное действие с использованием сторонней библиотеки» отдельным приложением, запускающимся из родителя (ещё одного), устанавливающего переменные. Хотя вам, конечно, виднее, поди ещё дополнительные ограничения есть.
Тут безусловно есть некое трюкачество, но это очень простой и компактный вариант, удобен тем, что не приходится выделять еще один модуль, экспортировать ф-ии и пр. только ради утсановки окружения. Зашаривать это решение не нужно и не думаю что когда либо потребуется. Выходит, что это делается ради единственной цели и в таком случае наше решение на мой взгляд оправдано. Приложение небольшое, пока библиотеки не грузит, поэтому первый экземпляр никому не мешает. Все это живет только на время выполнения некоторого непродолжительного действия.
Я вообще не понимаю, как можно в код процесса подгружать стороннюю библиотеку (как это делают всякие пунто и прочие программы), это же почти 100% вероятность труднообнаружимых багов, конфликтов, тормозов, зависаний, и т.д. Впрочем, что взять с разработчиков майкрософт — у них раньше вообще программы при установке клали свои библиотеки и конфиги в папку Windows.

Но справедливости ради, переменные окружения передаются в программу извне, и ставить их внутри самой программы через putenv() — это тоже неправильно. Вы должны конфигурировать библиотеку явно, через какую-нибудь функцию вроде fooLibraryInit({… configuration… } ). Переменные окружения — это если пользователь захочет что-то поменять.
> Я вообще не понимаю, как можно в код процесса подгружать стороннюю библиотеку

А куда ее тогда подгружать? Не понял смысла утверждения?

> Но справедливости ради, переменные окружения передаются в программу извне, и ставить их внутри самой программы через putenv() — это тоже неправильно. Вы должны конфигурировать библиотеку явно, через какую-нибудь функцию вроде fooLibraryInit({… configuration… } )

Такая вот библиотека, она получает конфигурацию частично через окружение. Там на самом деле еще хитрее — одна из подкомпонент, которая подгружается этой библиотекой так конфигурируется.
> А куда ее тогда подгружать? Не понял смысла утверждения?

В свое, отдельное адресное пространство. В многозадачной системе процессы специально изолированы друг от друга, и эти виндовые трюки с подгрузкой чужих библиоткек (а также игры с вызовами типа read/writeprocessmemory) — нарушение этой изоляции. Которое может влечь за собой трудно обнаружимые баги например.
> В свое, отдельное адресное пространство.

И взаимодействовать с библиотеками только через межпроцессные каналы? Это влечет за собой слишком большие накладные расходы.

> В многозадачной системе процессы специально изолированы друг от друга, и эти виндовые трюки с подгрузкой чужих библиоткек (а также игры с вызовами типа read/writeprocessmemory) — нарушение этой изоляции.

Динамические библиотеки есть в unix (.so) и windows (.dll), непонятно чем здесь windows выделяется. Писать в адресное пространство чужого процесса конечно нехорошо, но причем здесь это?

Взять практически любой исполняемый модуль — он зависит от массы разных динамических библиотек, те в свою очередь от других. Это совершенно стандартная практика на всех платформах. Если я правильно понял вы предлагаете все грузить в отдельных процессах и пользоваться межпроцессным взаимодействием. По моему это неприемлемо в плане производительности.
В случае перехвата нажатий клавиш, то, что вы написали, это бред. Человек не способен нажимать клавиши с такой скоростью, чтобы это вызвало хоть сколько-нибудь значительные накладные расходы.

> Взять практически любой исполняемый модуль — он зависит от массы разных динамических библиотек, те в свою очередь от других.

Покажите мне, каким образом, например, браузер Opera зависит от модуля pshook.dll (PuntoSwitcher Hook), которые написали криворукие ребята из Яндекса? Никаким. авторы оперы могут и не знать об этой программе. Есть разница между теми библиотеками, которые указаны в импортах исполняемого файла (которые явно подключил разработчик программы) и теми, которые без спросу лезут в адресное пространство всех процессов и там выполняются.

> В случае перехвата нажатий клавиш, то, что вы написали, это бред. Человек не способен нажимать клавиши с такой скоростью, чтобы это вызвало хоть сколько-нибудь значительные накладные расходы.

Я не говорил о перехвате нажатий клвиш, а в целом о любой задаче. Не все же существующие библиотеки обрабатывают нажатие клавиш. Даже в результате нажатия на клавишу может выполняться некое действие внутри которого будет обращение к десятку библиотек и если между ними всеми будет межроцессное взаимодействие, то время работы может неоправдано возрасти. Вызов становится тяжелым, требуется синхронизация, оборачивание и передача данных туда и обратно.

> Покажите мне, каким образом, например, браузер Opera зависит от модуля pshook.dll (PuntoSwitcher Hook), которые написали криворукие ребята из Яндекса?

Никаким. Забудем о хуках, таких библиотек может быть единицы в адресном пространстве. Кроме этого туда подгружена сотня других dll, с ними что прикажете делать?
Вы вообще ничего не поняли из моего первого комментария. Я нигде не предлагал грузить каждую динамическую библиотеку в отдельное адресное пространство.

У меня такое ощущение, что я объясняю вам элементарные вещи. Библиотеки, используемые программой, загружаются явно, по желанию разработчика программы, он знает о них, об их особенностях работы, он имеет возможность протестировать свою программу с ними и убедиться, что все работает. Никто не говорит, что их надо куда-то выносить. В этом нет необходимости.

В то же время, библиотеки, которые подгружаются сторонними программами от яндекса или программами идущими в поставке со всякими планшетами и прочим железом, грузятся сами, не спрашивая мнения разработчика. Как люди, которые лезут в чужой дом без спроса. Протестировать свой продукт на совместимость с ними он не может. Если программа свалится из-за них, пользователь будет жаловаться разработчику, и напишет в обзоре на сайте, что программа кривая (хотя на самом деле виноват не он).

> Забудем о хуках, таких библиотек может быть единицы в адресном пространстве.

Вообще-то мой комментарий относится ИМЕННО к таким и ТОЛЬКО к таким случаям.

Это типичный пример каши, которая была в голове разработчиков МС, так же как они раньше позволяли всем программам сваливать свой хлам в папку Windows (благополучно ломая всю систему в случае конфликта), так же они и позволяют программам разных разработчиков лезть в память друг к другу.

Я сейчас специально посмотрел — в память редактора кода scite подгрузились сами собой такие библиотеки:

dropboxext.13.dll
thgshell.x86.dll (от TortoiseHg)
intl3_tsvn.dll (от TortoiseSVN)
libaprutil_tsvn.dll
libapr_tsvn.dll
tortoisesvn.dll
tortoisestub.dll
tortoiseoverlays.dll
pshook.dll

Я удивляюсь, как мой компьютер вообще еще работает. Недаром Windows считается самой глючной платформой.
> Вы вообще ничего не поняли из моего первого комментария. Я нигде не предлагал грузить каждую динамическую библиотеку в отдельное адресное пространство.

Да, я неверно вас понял, вы говорили именно о хуках.
Но даже, если бы не было хука от Logitech, то в моем случае это не снимает проблемы которая описана в посте. Если исполняемый модуль зависел бы от нескольких компонент, а обычно так и есть, то нужно было бы следить, чтобы ни в коем случае не подгрузился msvcrt8 раньше явной подгрузки library.dll, что неудобно, т.к. те модули могут зависеть от других и т.д. Правильнее было бы полностью себя обезопасить от этого.

> Я сейчас специально посмотрел — в память редактора кода scite подгрузились сами собой такие библиотеки:
> dropboxext.13.dll
> thgshell.x86.dll (от TortoiseHg)
> intl3_tsvn.dll (от TortoiseSVN)
> libaprutil_tsvn.dll
> libapr_tsvn.dll
> tortoisesvn.dll
> tortoisestub.dll
> tortoiseoverlays.dll
> pshook.dll

Хуки были сделаны для перехвата очереди ввода, решение безусловно не самое удачное с точки зрения безопасности. Хотя сам механизм внедрения есть и в Linux — LD_PRELOAD, но не знаю используют ли его для перехвата ввода. В списке последняя dll видимо от punto switcher, другие может и не являются хуками, а грузятся по каким-то иным причнам? Тут надо взглянуть на дерево зависимостей. Не очень понятно зачем бы svn потребовалось перехватывать ввод. В целом мне кажется хуки не очень часто используются.
Библиотеки от SVN/TortoiseHg подгрузились, чтобы в диалоге открытия/сохранения файла отображать дополнительные иконки на файлах.
Only those users with full accounts are able to leave comments. Log in, please.