ROS Newsletter81

Материал из Русский WINE
Перейти к: навигация, поиск

Выпуск новостей ReactOS №81

Декорирование в C++

Те, кто имеет опыт использования сторонних библиотек при написании приложений на C++ наверняка уже поняли, о чём я хочу рассказать, и могут пропустить эти два абзаца и продолжить чтение с третьего, посвящённого проблемам, специфическим для ReactOS. Если же вы не знаете, о чём идёт речь, или хотите освежить суть вопроса в памяти, то продолжайте читать. Стандарт языка C++ описывает способ компиляции кода на C++. Компилятор для обеспечения совместимости должен строго следовать спецификациям стандарта, хотя ни один из известных мне компиляторов не поддерживает этот стандарт на 100%. Например, части стандарта, посвящённые шаблонам, довольно часто меняются. Существуют, однако, и ситуации, в которых поведение компилятора не стандартизировано, и реализация методов их обработки оставлена на усмотрение разработчиков самого компилятора. Основными двумя такими ситуациями являются обработка исключений и декорирование имён. Декорирование имён по большей части связано со способом присвоения компиляторами C++ уникальных названий функциям, классам, и функциям классов для исключения конфликта при объединении воедино нескольких модулей. Компоновщик столкнётся с проблемой, если обнаружит две одинаковые функции под названием "foo" без какой-либо возможности понять, какая из них вызывается кодом. Обработка исключений по большей части представляет собой лишь результат решения вопроса по размещению данных, необходимых при возникновении исключения в функции, и различные компиляторы выбирают свои способы хранения этой информации. Одни могут делать это лучше, чем другие, но, в основном, всё сводится к приоритетам, которые преобладали у разработчиков в момент проектирования компилятора.

Среди множества компиляторов C++, лишь небольшое количество декорируют имена дескрипторов одинаково. Основными из них являются GCC и компилятор C++ от Intel, оба из которых следуют спецификациям на бинарный интерфейс приложений (ABI) Itanium при декорировании. В GCC, начиная с серии выпусков версий 3.x., метод декорирования был изменён для соответствия спецификациям IA-64. Таким образом, далеко не обязательно, что в разных версиях одного и того же компилятора будет использоваться один и тот же метод декорирования имён. Как раз поэтому обычно сторонние библиотеки доступны для скачивания в нескольких версиях для GCC, Visual Studio, и любого другого поддерживаемого компилятора, использующего отличные от них спецификации. Даже без учёта различий в обработке исключений, вы можете столкнуться с проблемой несовместимости при попытках компоновки кода, скомпилированного разными компиляторами.

В Windows, Microsoft установила стандарт де-факто для бинарного интерфейса приложений, включающий в себя соглашения по декорированию имён и обработке исключений. Таким образом, большинство компиляторов для Windows, в той или иной степени следуют требованиям этого соглашения. И здесь начинаются проблемы для ReactOS. Поскольку для ReactOS важно воссоздать библиотеки, с которыми взаимодействуют все приложения Windows, нам необходимо иметь такой же метод декорирования при экспортировании функций. В настоящее время используется метод, при котором используется файл спецификации, чётко определяющий способ декорирования имён функций. Это рутинный ручной процесс, который может занять довольно много времени. Большинства описанных выше проблем можно избежать, если для сборки ReactOS использовать компиляторы от Microsoft. При этом способ декорирования имён и поддержка исключений стали бы аналогичны используемым в Windows, что привело бы к уменьшению вероятности возникновения ошибки в некоторых приложениях, пытающихся обратиться к несуществующим функциям. Недавнее фиаско, постигшее rbuild и связанное с поддержкой им несуществующих функций должно послужить нам предупреждением о том, что эти проблемы не всегда можно легко обнаружить. По крайней мере версия ReactOS, собранная с использованием MSVC, может быть использована как эталон при поиске причин возникновения проблем, позволяющий понять, появилась проблема при компиляции и компоновке, или же её следует искать в нашем коде.

Debug Page Heap

В течение нескольких лет для выявления и поиска повреждений памяти в ReactOS были разработаны различные инструменты, крайне необходимые в условиях плачевного состояния диспетчера памяти. Алексей Брагин написал код проверки целостности для старой реализации пула, в то время, как Михаэль Мартин (Michael Martin) придумал новый способ проверки при помощи функционала, встроенного в QEMU и предназначенного для наблюдения за состоянием памяти. В действительности, в Windows также имеется встроенная поддержка обнаружения повреждений в области памяти, где происходят динамические выделения памяти; эта область памяти называется кучей. Отладочная куча может использоваться разработчиками для проверки своих приложений на наличие перерасхода памяти, также она является очень полезным инструментом для выявления повреждений памяти и прочих нужд. Доступ к этому отладочному пулу может быть активирован в реестре или с помощью предоставляемого Microsoft приложения gflags.

Когда для приложения активировано использование отладочной кучи, все распределения используемой им памяти производятся отдельным диспетчером кучи. Этот диспетчер кучи не использует обычные оптимизации, и, фактически, работает медленнее за счёт добавления дополнительной информации, необходимой для учёта использования ресурсов, в каждый выделяемый блок памяти. Одно из этих дополнений – использование страниц защиты в каждом выделенном блоке, которые инициируют исключение, если приложение попытается получить доступ к памяти вне границ выделенного блока. Даже не принимая во внимание полное отсутствие оптимизации, затраты ресурсов, необходимые для обеспечения учёта, довольно значительны. Алексей провел приблизительно полторы недели, разрабатывая этот второй диспетчер кучи (также называемый Debug Page Heap или DPH) для ReactOS, и теперь он является частью кодовой базы проекта. Время для его создания было выбрано крайне удачно, поскольку разработчики и тестеры недавно обнаружили колоссальное количество повреждений пула, порождённых комбинацией нового диспетчера кучи, более строго следующего стандартам, и неаккуратного кода в других частях операционной системы и приложениях, которые продолжают повреждать кучу. Не прекращающийся поток тестов, патчей и повторных тестов шёл при подготовке к выпуску версии 0.3.13, и нам, надеюсь, удастся избавиться от большинства выявленных проблем.

Временные файлы

Одной из регрессий, от которых хотели избавиться и тестеры и разработчики, была невозможность установки и использования Adobe Flash. Используя данные отчётов, Пьер Швейцер (Pierre Schweitzer) начал заниматься поиском проблемы, тем более, что многие из тестеров утверждали, что заключалась она в создании файлов во время процесса установки. В конечном итоге проблема была обнаружена, и состояла она в способе создания временных файлов системой ReactOS, а ещё точнее кодом ReactOS, импортированным из Wine. Эта конкретная версия кода была повреждена и повторяла имя файла, которое передавалась функции для создаваемого файла. В более новой версии ошибка была устранена, однако Пьер обнаружил что способ, который Wine использует для создания имён файлов в случае, если они явно не определены, отличен от используемого в Windows. Таким образом, Пьер решил переписать эту функцию для того, чтобы алгоритм её работы стал более похож на используемый в Windows. Хотя патч Пьера и позволил производить установку Flash, однако Flash сама по себе по-прежнему остаётся неработоспособной из-за других регрессий.

Newsletters
30-39 #30#31#32#33#34#35#36#37#38#39
40-49 #40#41#42#43#44#45#46#47#48#49
50-59 #50#51#52#53#54#55#56#57#58#59
60-69 #60#61#62#63#64#65#66#67#68#69
70-79 #70#71#72#73#74#75#76#77#78#79
80-89 #80#81#82#83#84#85#86#87#88#89
90-99 #90#91#92#93#94#95#96#97#98#99