Как обнаружить бреши API в C++
Как я могу обнаружить несовместимые изменения API в C++? (не ABI, а изменения API)
Где совместимые изменения - это вещи, которые не могут нарушить компиляцию кода с использованием API, например:
- параметры добавлены в метод с аргументом по умолчанию
- методы, добавленные в класс
- участники добавлены в класс
- добавлены классы
- порядок членов или методов изменен
- комментарии / изменения документации
А несовместимые изменения - это вещи, которые потенциально могут нарушить компиляцию кода с использованием API, например:
- удаленные аргументы, (публичные / защищенные) методы, члены, классы
- введите изменения аргументов или членов
- изменения имени открытых / защищенных членов или методов
- классы перемещены из одного заголовка в другой
2 ответа
OP прав, считая, что синтаксический анализ C++, вероятно, необходим. Вероятно, глубокие рассуждения тоже.
Я думаю, что способ поставить вопрос,
для определенного набора применений API в существующем приложении меняет ли API изменение или разрыв приложения?
Если вы не ограничиваете себя определенным набором применений, почти любое изменение API изменит его семантику. Иначе зачем их делать (по рефакторингу по модулю?). И если вы используете полный набор функций API в приложении, то его семантика тоже должна измениться.
С определенным набором применений можно, вероятно, определить, какие свойства API могут влиять на конкретные применения, и определить, действительно ли они влияют. В конечном итоге вам необходимо точно проанализировать исходный код, чтобы определить конкретный набор применений и контекст, в котором они используются. Вы также должны определить семантические свойства, от которых зависит существующее приложение, включая свойства, предоставляемые устаревшим API. Наконец, вам нужно определить свойства, определенные новым API, и по-прежнему проверять поддержку потребностей приложения.
В общем, вам нужно проверить теорему по свойствам программы, чтобы проверить это. И, хотя технология доказательства теорем значительно продвинулась за последние 50 лет, AFAIK сказал, что технология недостаточно сильна, чтобы взять в общем произвольные свойства программы и доказать их, не говоря уже о преодолении проблемы рассуждений о произвольно сложных программах.
Рассматривать:
// my application
int x=0;
int y=foo(x); // API ensures that fail...
if (y>3) then fail(); // shouldn't happen
exit();
// my legacy API
int foo(int x) { return x+1; }
Теперь представьте, что API изменен на:
// my new API
int foo(int x) { return x+2; }
Приложение по-прежнему работает правильно. Как насчет:
// my new API
int foo(int x) { return TuringMachine(x); }
Как мы собираемся доказать, что TuringMachine(x) выдает значение< 3? Если мы не можем сделать это для таких крошечных программ, как мы собираемся сделать это для тех, которые мы пишем на практике?
Теперь вы можете ограничить набор изменений, которые вы будете рассматривать, просто "синтаксическими" операциями, такими как "метод перемещения", "добавить параметр с начальным значением" и т. Д.
Вам все еще нужно будет проанализировать исходную программу и измененные API и проверить, что синтаксические свойства подразумевают семантические свойства, которые не повреждают исходную программу. Скорее всего, вам понадобится контроль и анализ потоков данных, анализ псевдонимов, чтобы беспокоиться об указателях и т. Д., И инструмент в лучшем случае сможет определить ограниченное число случаев, когда никаких изменений не произошло.
Я уверен, что есть исследовательские работы на эту тему. Быстрая проверка на scholar.google.com не показала ничего очевидного.
См. Вкладку "Совместимость с исходным кодом" отчета инструмента ABICC. Большинство упомянутых изменений API и разрывов API обнаруживаются этим инструментом.
Есть два подхода к использованию инструмента. Оригинал с помощью анализа заголовочных файлов и новый с помощью анализа отладочной информации библиотеки ( [1]). Используйте второй. Это надежнее и проще.
Вы можете найти некоторые примеры отчетов здесь: http://abi-laboratory.pro/tracker/
Учебное пособие: https://sourceware.org/glibc/wiki/Testing/ABI_checker