は、ここでの具体的な例です
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:true
とfold_state_callstack
に~after:false
パラメータを置き換え、文の後の状態を取得します。以前のバージョンのコードでは、事前状態の値をすでにバインドしていた関数が使用されていましたが、そのような関数はポスト状態にエクスポートされていませんでした。したがって、fold_state_callstack
を使用する必要がありますコールスタックごとの状態)。
'Db.Value.get_stmt_state'によって返される状態は、* variables *から抽象的な値へのマッピングではありませんが、それよりも強力です。なぜ、変数の値を取得するのが少し複雑です。つまり、リンクされた質問に対する解答のコメントは、それが成功したと結論づけているようです。使用しているFrama-Cのバージョンを教えてください。 – anol
@anolが正しいです。スカラー変数の値だけに興味があるなら、 'x'がFrama-C変数(' varinfo')であると仮定して 'lval_to_loc'の' lval'引数に '(Var x、NoOffset) – byako
あなたが言ったコメントのなかで、この部分は何ですか? '(Kstmt stmt)lv' lvとは何ですか? Kstmtはキャストかそれとも何か? –