Анализ программы с заданным входом

У меня есть программа на C, и я хочу отслеживать все условия ветвления, которые принадлежат пути выполнения, соответствующему конкретному вводу. Например, рассмотрим простую программу:

#include <stdio.h>
#include <string.h>
int test(char* a) {
    if (strcmp(a, "123") == 0)
       return 0;

    if (strcmp(a, "123") < 0)
       return -1;
    else 
       return 1;
  }

   int main() {
      char* a;
      return test (a);
  } 

С a = "1234"программа возврата 1 и соответствующее условие пути strcmp(a, "123") > 0, Я хочу собрать strcmp, "123" и значение этого оператора (-1). Есть ли подход, который позволяет мне сделать это? Сначала я подумал о работе с каким-то парсером C, но, похоже, не все так просто. Чтобы получить значения параметров, мы должны иметь дело с анализом указателя или вызовом внешней библиотеки, который я не знаю, как решить.

1 ответ

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

Но парсера вряд ли достаточно; вам нужен инструмент, который может преобразовывать имена в объявления и выражения в типы, который может извлекать потоковые графы, которые могут делать точки для анализа и особенно функции-точки-для анализа, и, наконец, что-то, что может построить граф вызовов с учетом всего этого, Это означает, что вам нужна компиляторная среда для решения проблемы.

Возможно, вы можете согнуть GCC (трудно, он действительно хочет быть компилятором) или Clang (хочет быть, но предназначен для других целей), но они хотят компилировать отдельные программы, и вам нужно что-то, что может обработать набор программ (поскольку программы на Си обычно создаются именно так). Наш инструментарий реинжиниринга программного обеспечения DMS разработан специально для поддержки такого рода пользовательских задач и имеет все необходимое оборудование. (DMS также поддерживает определенные диалекты C).

Сделав выбор в виде фреймворка, код для навигации по интересующему пути потока вряд ли будет простым. Общая рекомендация будет заключаться в том, чтобы "проанализировать источник, применить все вышеперечисленные анализаторы, а затем пройтись по структурам данных с помощью API-интерфейсов, предлагаемых инструментами", уделяя особое внимание API-интерфейсам, которые следуют путям потока управления. Весь этот код вряд ли вписывается в пример. И это будет значительно варьироваться в зависимости от того, какую основу вы выберете. Я не знаю деталей GCC или Clang, но я не думаю, что они предлагают вам какие-либо простые способы записать символическое описание пути (например, соединение условных выражений). Я могу сказать вам, что DMS (по замыслу) имеет явную поддержку для создания символических формул, подобных этой.

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

Другие вопросы по тегам