2016-11-18 16 views
0

Я использую версию frama-c Aluminium-20160502, и я хочу узнать зависимости в большой программе. При использовании опции -deps в командной строке я обнаружил, что некоторые зависимости отсутствуют. В частности, когда несколько условий объединяются в один, если анализ зависимости останавливается всякий раз, когда одно условие ложно. В этом примере здесь:Сделайте зависимости от изображения Frama-c даже от «мертвых ветвей»

#include<stdio.h> 
#include<stdbool.h> 

/*Global variable definitions*/ 
bool A = true; 
bool B = false; 
bool C = true; 
bool X; 
bool Y; 

bool res; 


void main(){ 

     if (A && B && C) { 
       res = X; 
     }else res = Y; 
} 

когда я пытаюсь: frama-c -deps program.c

Frama показывает следующие зависимости:

[от] ====== ЗАВИСИМОСТИ COMPUTED ======

Эти зависимости сохраняются при завершении для выполнения, которые завершаются:

[from] Функция main: res FROM A; B; Y

[от] ====== END зависимостей ======

поэтому не достигает условие С, потому что уже B ложно.

Интересно, есть ли способ сообщить Frama для вычисления всех зависимостей, даже если условие не выполняется. Я пробовал с опцией -slevel, но без каких-либо результатов. Я знаю, что есть способ использовать интервал Frama_C_interval (0,1), но когда я его использую, переменная, использующая эту функцию, не отображается в зависимостях. Я хотел бы получить X и Y, зависящие от A, B, C и res, зависящие от A, B, C, X, Y

Любые идеи?

+0

Обратите внимание, что то, что вы называете «мертвой ветвью», представляет собой синтаксическую структуру, которая не имеет семантического влияния на выполнение программы (например, «&& true»). Поскольку анализ зависимости Frama-C основан на семантике, вам, вероятно, придется либо «обмануть» их в рассмотрение посторонней ветви (например, «volatile», «Frama_C_interval» и т. Д.), Либо попытаться разработать синтаксический анализ (например, с помощью посетитель), который вычислил бы ваше понятие синтаксической зависимости. – anol

ответ

0

Плагин From использует результаты плагина анализа значений. В вашем примере значения A и B достаточно точны, что Значение позволяет сделать вывод, что условие полностью определено (поскольку оператор && лениво оценивается слева направо) до достижения C, поэтому C никогда не влияет на результат и следовательно, не является зависимостью с точки зрения От.

К сожалению, Frama_C_interval не может быть использован непосредственно на глобальных инициализаторах:

user error: Call to Frama_C_interval in constant. 

Вы можете, однако, использовать "взломать" (не всегда лучшее решение, но здесь работает):

volatile bool nondet; 
bool A = nondet; 
bool B = nondet; 
bool C = nondet; 
... 

Обратите внимание, что поскольку nondet равно volatile, каждой переменной A, B и C присваивается другое недетерминированное значение.

В этом случае стоимость должна учитывать обе ветви условными, и поэтому C становится зависимость в вашем примере, так как возможно, что C будет читаться во время выполнения main. После этого вы будете иметь:

 These dependencies hold at termination for the executions that terminate: 
[from] Function main: 
    res FROM A; B; C; X; Y 

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

Это, однако, касается только некоторых видов зависимостей.Как упоминалось в главе 6 раздела Value Analysis user manual, плагин From вычисляет функциональные, императивные и операционные зависимости. Они делают не включают косвенные управляющие зависимости, которые являются такими, как X from A, B, C, как вы упомянули. Для них нужен плагин PDG (Program Dependence Graph), но в настоящее время он не имеет текстового вывода зависимостей. Вы можете использовать -pdg, чтобы вычислить его, а затем -pdg-dot <file>, чтобы экспортировать граф зависимостей в формате dot (graphviz). Вот что я получаю за main функции (с помощью летучего хак, как уже упоминалось ранее):

PDG for the main function

Наконец, в качестве примечания: -slevel в основном используется для улучшения точности, но в вашем примере вы уже имеют слишком много точность (то есть, значение уже может сделать вывод, что C никогда не читается внутри main).

+0

Большое спасибо за ваш ответ, это было очень полезно. Я попытался с параметром -pdg, но для более крупных программ немного беспорядочно найти зависимости на глаз. Однако очень интересно волатильное определение и решает уже проблему, если она используется для каждой переменной. –

+0

К сожалению, это решение работает только частично, потому что, когда значение A, B или C изменяется во время исполнения, тогда ленивая оценка заставляет зависимые элементы. Итак, мне нужно как-то отбросить эту ленивую оценку в более общем решении, так что Frama-C следует всем возможным путям выполнения. –

+0

Будет ли смысл объявлять A, B и C как 'volatile' сами? Каждое чтение/запись на них будет тогда недетерминированным. Но это может изменить семантику вашей программы таким образом, чтобы она не была предназначена. – anol