[ocaml-ctypes] Logging function calls
Jeremy Yallop
yallop at gmail.com
Sat Sep 13 12:20:25 BST 2014
On 12 September 2014 10:15, Thomas Braibant <thomas.braibant at gmail.com> wrote:
> I would like to log function calls using something like the following code:
>
> let rec log:
> type a. a fn -> a -> a =
> function
> | Static.Returns ty ->
> fun result ->
> Printf.printf "<- %s\n%!" (string_of ty result);
> result
> | Static.Function (ty, fn) ->
> fun f x ->
> Printf.printf "-> %s\n%!" (string_of ty x);
> log fn (f x)
>
> This works beautifully for simple enough function arguments. However,
> I would also like to display a bit more than what is currently
> available.
> Two quick examples come to mind.
>
> First, printing the name of manifest constants (e.g., defined in C
> using #define FOO 0x0001337). I would like to log FOO rather than its
> integer value. If I provide a correct printing function, it might even
> produces correct C code.
>
> Second, a bit more akward, printing the content of structs that are
> passed by reference to functions. I do not see a way to print that
> information as valid C, but it would be tremendously useful in my
> logs.
I think that you can do what you want by matching a little deeper on
"ty". Here's a function that prints C values, dereferencing
pointers-to-structures rather than just printing their addresses:
let rec format_val : type a. a typ -> Format.formatter -> a -> unit =
fun t fmt -> let open Static in match t with
| Pointer (Struct _ as s) ->
fun v -> Format.fprintf fmt "pointer to %a" (format_val s) !@v
| t -> Ctypes.format t fmt
You can then call format_val instead of string_of inside your log function:
let rec log:
type a. a fn -> a -> a =
function
| Static.Returns ty ->
fun result ->
Format.(fprintf std_formatter) "<- @[%a@]@\n%!" (format_val ty) result;
result
| Static.Function (ty, fn) ->
fun f x ->
Format.(fprintf std_formatter) "-> @[%a@]@\n%!" (format_val ty) x;
log fn (f x)
Here are the results, logging the results of passing the address of an
uninitialized struct to the identity function:
# let s = structure "s";;
val s : '_a structure typ = struct s
# let i = field s "i" int;;
val i : (int, ('_a, [ `Struct ]) structured) field = <abstr>
# let j = field s "j" float;;
val j : (float, ('_a, [ `Struct ]) structured) field = <abstr>
# let () = seal s;;
# let v = make s;;
val v : ('_a, [ `Struct ]) structured = {
i = -486857096, j = 4.5857492245e-41
}
# log (ptr s @-> returning (ptr s)) (fun x -> x) (addr v);;
-> pointer to { i = -486857096, j = 4.5857492245e-41 }
<- pointer to { i = -486857096, j = 4.5857492245e-41 }
- : '_a structure ptr = (struct s*) 0x95fc40
More information about the Ctypes
mailing list