2016-03-21 9 views
1

私は、価値分析を使ってFrama-Cのためのプラグインを開発しています。 私は単に各ステートメントの後に変数(値)の状態を出力したい(私は解決策は簡単だと思いますが、わかりませんでした)。Frama-Cプラグインの開発:価値分析の結果を得る

訪問者のvstmt_auxメソッドでDb.Value.get_stmt_stateの現在の状態を取得しました。

どのように変数の値を取得できますか?

PS:私はこの記事を見つけたが、それは助けにはならなかった、本当の解決策は存在しない、と説明の助けを借りて、私はそれを行うことができませんでした: How to use functions in Value.Eval_expr, Value.Eval_op etc modules of Frama-c Value plugin

+2

'Db.Value.get_stmt_state'によって返される状態は、* variables *から抽象的な値へのマッピングではありませんが、それよりも強力です。なぜ、変数の値を取得するのが少し複雑です。つまり、リンクされた質問に対する解答のコメントは、それが成功したと結論づけているようです。使用しているFrama-Cのバージョンを教えてください。 – anol

+0

@anolが正しいです。スカラー変数の値だけに興味があるなら、 'x'がFrama-C変数(' varinfo')であると仮定して 'lval_to_loc'の' lval'引数に '(Var x、NoOffset) – byako

+0

あなたが言ったコメントのなかで、この部分は何ですか? '(Kstmt stmt)lv' lvとは何ですか? Kstmtはキャストかそれとも何か? –

答えて

7

は、ここでの具体的な例です

open Cil_types 

(* Prints the value associated to variable [vi] before [stmt]. *) 
let pretty_vi fmt stmt vi = 
    let kinstr = Kstmt stmt in (* make a kinstr from a stmt *) 
    let lval = (Var vi, NoOffset) in (* make an lval from a varinfo *) 
    let loc = (* make a location from a kinstr + an lval *) 
    !Db.Value.lval_to_loc kinstr ~with_alarms:CilE.warn_none_mode lval 
    in 
    Db.Value.fold_state_callstack 
    (fun state() -> 
     (* for each state in the callstack *) 
     let value = Db.Value.find state loc in (* obtain value for location *) 
     Format.fprintf fmt "%a -> %[email protected]" Printer.pp_varinfo vi 
     Locations.Location_Bytes.pretty value (* print mapping *) 
    )() ~after:false kinstr 

(* Prints the state at statement [stmt] for each local variable in [kf], 
    and for each global variable. *) 
let pretty_local_and_global_vars kf fmt stmt = 
    let locals = Kernel_function.get_locals kf in 
    List.iter (fun vi -> pretty_vi fmt stmt vi) locals; 
    Globals.Vars.iter (fun vi _ -> pretty_vi fmt stmt vi) 

(* Visits each statement in [kf] and prints the result of Value before the 
    statement. *) 
class stmt_val_visitor kf = 
    object (self) 
    inherit Visitor.frama_c_inplace 
    method! vstmt_aux stmt = 
     (match stmt.skind with 
     | Instr _ -> 
     Format.printf "state for all variables before stmt: %[email protected]%[email protected]" 
      Printer.pp_stmt stmt (pretty_local_and_global_vars kf) stmt 
     | _ ->()); 
     Cil.DoChildren 
    end 

(* usage: frama-c file.c -load-script print_vals.ml *) 
let() = 
    Db.Main.extend (fun() -> 
     Format.printf "computing [email protected]"; 
     !Db.Value.compute(); 
     let fun_name = "main" in 
     Format.printf "visiting function: %[email protected]" fun_name; 
     let kf_vis = new stmt_val_visitor in 
     let kf = Globals.Functions.find_by_name fun_name in 
     let fundec = Kernel_function.get_definition kf in 
     ignore (Visitor.visitFramacFunction (kf_vis kf) fundec); 
     Format.printf "[email protected]") 

これは理想からかけ離れており、出力は次のようになります。印刷する方法を、それぞれローカルおよびグローバル変数のために、与えられた関数内の各ステートメントの前の値によって計算された結果は、(下から上への関数を読んで)単純にCvalue.Model.pretty stateを使用するよりも醜いですが、それはさらなる修正のための基礎として役立ちます。

このスクリプトはFrama-Cマグネシウムでテストされています。

単に~after:truefold_state_callstack~after:falseパラメータを置き換え、文の後の状態を取得します。以前のバージョンのコードでは、事前状態の値をすでにバインドしていた関数が使用されていましたが、そのような関数はポスト状態にエクスポートされていませんでした。したがって、fold_state_callstackを使用する必要がありますコールスタックごとの状態)。

+0

ありがとう、それはまさに私が探していたものでした:) –

+0

ステートメントの後に値を取得する方法はありますか? –

+0

もう1つの質問:出力はなぜ形式ですか?c - > {{NULL - > {17}}} このNULLとは何ですか? (これは前にnullではありませんか?) –

関連する問題