научная статья по теме ОБРАТНАЯ СОВМЕСТИМОСТЬ ПРОГРАММНЫХ ИНТЕРФЕЙСОВ: ШАГИ К АВТОМАТИЧЕСКОЙ ВЕРИФИКАЦИИ Математика

Текст научной статьи на тему «ОБРАТНАЯ СОВМЕСТИМОСТЬ ПРОГРАММНЫХ ИНТЕРФЕЙСОВ: ШАГИ К АВТОМАТИЧЕСКОЙ ВЕРИФИКАЦИИ»

ПРОГРАММИРОВАНИЕ, 2012, No 5, с. 72-86

= ВОСЬМАЯ ЕРШОВСКАЯ КОНФЕРЕНЦИЯ ПО ИНФОРМАТИКЕ (ПСИ'11) =

УДК 681.3.06

ОБРАТНАЯ СОВМЕСТИМОСТЬ ПРОГРАММНЫХ ИНТЕРФЕЙСОВ: ШАГИ К АВТОМАТИЧЕСКОЙ

ВЕРИФИКАЦИИ

© 2012 г. А.В. Пономаренко, В.В. Рубанов Лаборатория РОСА 123557 Москва ул. Пресненский Вал, 14 E-mail: andrey.ponomarenko@rosalab.ru, vladimir.rubanov@rosalab.ru Поступила в редакцию 12.12.2011 г.

В данной статье рассматриваются проблемы контроля обратной совместимости между новыми и старыми версиями базовых программных компонентов (библиотек). Окружение Linux рассматривается в качестве основного примера. Нарушение обратной совместимости в новых версиях программных компонентов может привести к некорректной работе (на бинарном уровне) или невозможности перекомпиляции (на уровне исходных кодов) пользовательских приложений, нацеленных на использование предыдущих версий, при попытке перехода на новую версию компонента. В статье описаны типичные причины, приводящие к нарушению обратной совместимости на бинарном уровне, а также представлен новый подход к автоматическому выявлению этих причин на стадии разработки программных компонентов (основное внимание уделено анализу изменений в структуре интерфейсов). Языки Си/Сн—h взяты за основу для демонстрации подхода, хотя предлагаемый подход может быть применен и к другим языкам программирования, таким как Java или языкам из Microsoft Visual Studio (С#, Visual Basic и др.). В отличие от существующих аналогов, предлагаемый подход может выявлять широкий спектр проблем обратной совместимости благодаря анализу изменений в сигнатурах функций и определений типов данных, извлекаемых из заголовочных файлов компонентов в дополнение к анализу символов исполняемых файлов. Также в данной статье рассмотрен инструмент, реализующий предлагаемый подход, и результаты практического применения этого инструмента. Шаги к дальнейшему улучшению качества автоматической верификации обратной совместимости обсуждаются в заключении.

1. ВВЕДЕНИЕ Программные компоненты, предоставляющие программные интерфейсы (API) для других программных компонентов, играют важную роль в архитектуре вычислительных систем. Такие компоненты могут быть объединены вместе для создания программных платформ. Обычно, выделяют три основных слоя в программном стеке вычислительных систем -ядро, системные библиотеки и приложения. Системные библиотеки основаны на ядре и других системных библиотеках для предоставления API высокого уровня для пользовательских приложений.

Современные операционные системы и, особенно, Linux состоят из огромного количества системных библиотек и других программных компонентов, которые активно развиваются и довольно часто обновляются до новых версий (в среднем, раз в несколько месяцев). Разработка приложений ведется параллельно с разработкой библиотек. В результате этого различные версии приложений разрабатываются для разных версий системных компонентов. При обновлении или установке нового приложения в систему, также должны быть обновлены и необходимые системные библиотеки, чтобы удовлетворить требованиям нового приложения.

При этом очень важно удостовериться, что новые версии библиотек совместимы на бинарном уровне с предыдущими версиями, и остальные приложения могут корректно работать с новыми версиями библиотек.

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

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

Изменения в интерфейсе можно разделить на преднамеренные и непреднамеренные изменения, которые могут нарушить обратную совместимость. Преднамеренные изменения возникают, когда разработчики библиотеки решают, что нарушение совместимости в данном случае необходимо и оправдано пользой от добавления новой функциональности. Непреднамеренные изменения возникают, когда разработчики не осознают, что некоторые изменения в интерфейсе могут привести к нарушению обратной совместимости (на бинарном уровне, уровне исходных кодов или на обоих), так как они сконцентрированы на решении функциональных проблем на момент внесения изменений или просто недостаточно квалифицированны для поддержания совместимости. Лучшим способом для выявления непреднамеренных изменений

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

Известно много историй, когда разработчики библиотек узнавали о нарушении обратной совместимости от своих пользователей уже после выпуска новых версий. Например, в октябре 2007 года [1] разработчики библиотеки ИЪв^ ёе++ случайно изменили порядок объявления методов в одном из классов и тем самым изменили структуру виртуальной таблицы этого класса, что нарушило обратную совместимость с предыдущими версиями библиотеки. Это был яркий пример непреднамеренного нарушения обратной совместимости. В 2009 году [2] разработчики библиотеки РгееТуре2 изменили структуру типа данных Р8_Роп^п&Кес, что привело к нарушению совместимости и недовольству многих пользователей, в результате чего разработчики были вынуждены вернуть прежнюю структуру этого типа в следующих версиях библиотеки. Среди недавних примеров (ноябрь 2010) вызвавших общественный резонанс можно выделить случайное удаление версий бинарных символов в библиотеке ИЪхш12 версии 2.7.8 [3].

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

определить семантические (поведенческие) изменения в функциях, которые также могут нарушить обратную совместимость. Поэтому мы рекомендуем выполнять дополнительные проверки для таких изменений. Обычно, для поиска проблем обратной совместимости, вызванных изменениями в семантике функций, рекомендуется использовать набор модульных тестов [4-9]. Существуют различные подходы к автоматизации разработки таких тестов с различным соотношением цена/качество, которые коротко рассмотрены в заключении данной статьи.

Языки Си/С++ и Linux взяты в качестве окружения для объяснения подхода к решению проблемы, поставленной в данной работе. Выбор операционной системы объясняется тем, что описанная проблема поддержания обратной бинарной совместимости наиболее актуальна именно для Linux в силу сложившихся методов распространения приложений (без включения в установочный пакет копий всех необходимых библиотек), а также в силу специфики разработки этой операционной системы (часто несогласованная разработка большим количеством энтузиастов по всему миру). Выбор же языков программирования Си/С++ объясняется наибольшей чувствительностью этих языков к изменениям в исходном коде с точки зрения обратной бинарной совместимости. Как в Си, так и в С++ диагностика проблем обратной совместимости усложняется наличием неуправляемого кода и отсутствием диагностических сообщений при возникновении проблемы (например, при нарушении стека вызова функции). В С++ ситуация усложняется наличием полиморфизма, реализованного через механизм виртуальных таблиц, малейшее изменение в которых может привести к нарушению обратной совместимости всех производных классов (например, при добавлении новой виртуальной функции). Таким образом, не только изменения в старых функциях, но даже добавление новых может нарушить обратную бинарную совместимость кода на языке С++.

Данная статья состоит из трех основных частей. В первой части представлена классификация наиболее часто встречающихся

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

2. ТИПЫ ПРОБЛЕМ ОБРАТНОЙ БИНАРНОЙ СОВМЕСТИМОСТИ И ИХ ПРИЧИНЫ

Мы установили 8 основных типов изменений в исходном коде на языках Си/С++, которые могут вызывать различные проблемы обратной бинарной совместимости. Данный анализ был проведен на основе доступных работ, описывающих правила разработки библиотек под платформу Linux [10-12]. Также были изучены соглашения вызова Си/С++ функций в стандартах прикладного бинарного интерфейса (ABI) для наиболее распространенных архитектур процессора, таких как x86 [13], x86_64 [14], PowerPC [15], Itanium [16, 17], S390 [18] и ARM [19]. Мы продолжаем поиск д

Для дальнейшего прочтения статьи необходимо приобрести полный текст. Статьи высылаются в формате PDF на указанную при оплате почту. Время доставки составляет менее 10 минут. Стоимость одной статьи — 150 рублей.

Показать целиком