问题
I want to develop a Frama-C-Plugin, where I get the values of the current statement.
With the help of this post Frama-C Plugin development: Getting result of value-analysis I was able to print the values of the statements, but Pointers were not shown the way I need it.
With the help of the comments, I was able to print the whole state (not only the variables of the statement).
Can I combine these two: Get the variables of the statement, but also with pointers dereferenced (the value)?
For example, printing a non-pointer after statement x=1
results in x -> {{ NULL -> {1} }}
, while printing a pointer, after a statement like *x=3, results in x -> {{ y -> {0} }}
because the 0 is the offset of the variable, but I want to get the value where the pointer points to, in the example 3.
The way I want it, would be to get something like that: x -> 3
.
Even better would be to get a tuple of (String varname, int value)
, so I can print it myself.
回答1:
The value of a variable depend on its type. So if the variable has type int
, its value is an integer, but if the variable has the type int*
, its value is the address of an int
variable. The variable may have many other types such as structure, array, etc.
From you example, it seems that you want to get the value of the variable pointed by the pointer. Notice that in some cases, this is not a valid operation...
Anyway, I suppose that you can extract this function to print a lvalue from the previous answer in Frama-C Plugin development: Getting result of value-analysis:
let pretty_lval fmt stmt lval =
let kinstr = Kstmt stmt in (* make a kinstr from a stmt *)
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 -> %a@." Printer.pp_lval lval
Locations.Location_Bytes.pretty value (* print mapping *)
) () ~after:false kinstr
You can then print the information you are looking for with:
if Cil.isPointerType vi.vtype then
let lval = (Mem (Cil.evar vi), NoOffset) in
pretty_lval fmt stmt lval
来源:https://stackoverflow.com/questions/36276698/frama-c-getting-the-values-of-statement