【问题标题】:Frama-C: Getting the values of statementFrama-C:获取语句的值
【发布时间】:2018-01-05 20:17:08
【问题描述】:

我想开发一个 Frama-C-Plugin,用于获取当前语句的值。

在这篇文章 Frama-C Plugin development: Getting result of value-analysis 的帮助下,我能够打印语句的值,但指针没有按我需要的方式显示。

在 cmets 的帮助下,我能够打印整个状态(不仅仅是语句的变量)。

我可以将这两者结合起来:获取语句的变量,还可以使用取消引用的指针(值)?

例如,在语句x=1 之后打印非指针会导致x -> {{ NULL -> {1} }},而在像 *x=3 这样的语句之后打印指针会导致x -> {{ y -> {0} }},因为 0 是变量的偏移量,但我想获取指针指向的值,在示例 3 中。 我想要的方式是得到类似的东西:x -> 3

最好是得到一个(String varname, int value) 的元组,这样我就可以自己打印了。

【问题讨论】:

  • “指针未正确显示”是什么意思?也许您应该编辑您的问题以添加一个示例,说明您得到了什么以及您想看到什么。
  • 所以你要得到的是(*x)的值,而不是(x)的值。要知道一个变量是否是一个指针,你可以测试它的类型(Cil.isPointerType vi.vtype),然后,你必须构建左值*x(类似Lval (Mem ...,NoOffset))并用它来询问它的值。
  • ... 部分是什么?只是 varinfo 字段?如何从 varinfo 中获取偏移量?取消引用指针时,这将是必需的(或者我没有得到你想说的)?
  • 您应该查看cil_types.mli 文件,您可以在其中找到所有这些数据的定义,以及有关如何构建它们的一些说明。您需要取消引用,因为您想获得*x 的值。如您所见,如果您询问x 的值,您会得到它指向y(在您的示例中),这确实是指针的值。
  • 我查看了 cil_types.mli 中的定义:Mem 需要一个表达式。我从哪里得到这个?我通过 Kernel_function.get_locals 获得了 varinfos,但我看不到类似的函数来获取表达式?有没有显示我想要的示例代码?我找不到好的文档或教程。

标签: ocaml frama-c


【解决方案1】:

变量的值取决于它的类型。因此,如果变量的类型为int,则其值为整数,但如果变量的类型为int*,则其值为int 变量的地址。变量可能有很多其他类型,例如结构体、数组等。

从你的例子看来,你想获取变量的值 由指针指向。请注意,在某些情况下,这不是一个有效的操作...

无论如何,我想你可以从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

然后您可以打印您正在寻找的信息:

if Cil.isPointerType vi.vtype then
  let lval = (Mem (Cil.evar vi), NoOffset) in
  pretty_lval fmt stmt lval

【讨论】:

  • 谢谢,这回答了我关于指针的问题。现在有没有办法获取值并将其存储在 ocaml 变量中,而不是打印它?以某种方式通过调用以值(来自解决方案)作为参数的函数?
  • 什么意思?上面的value 一个ocaml变量。也许你的意思是一个字符串变量?如果是这种情况,您可以使用Format.asprintf,但这是一个 ocaml 问题。
  • 我的意思是:我想获取存储在变量中的值。例如:如果我有 {{ NULL -> {0} }},我想将 0 存储在 Ocaml int 变量中(或将其添加到列表或类似的东西中)。使用 asprintf,我得到了字符串(带括号,->,NULL ...)。有没有办法通过 Frama-C 函数获取值,还是我必须拆分字符串?
  • 尝试Db.Value.pretty 而不是Locations.Location_Bytes.pretty。我认为对于您的情况,它会更简单。
  • 谢谢,正是我需要的:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多