From d513789f245770e176f0a7191925fb378a46493c Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Tue, 10 May 2016 17:50:13 +0100 Subject: [PATCH 01/13] CP-17268 Integrate bisect_ppx for coverage profiling. Bisect dumps it report by registering a function through at_exit. This wasn't called by xenopsd. We added a handler to catch the SIGTERM signal used by the systemd service framework to stop the service. This leads to the profiling data being dumped. Signed-off-by: Christian Lindig --- _oasis | 120 +++++++++++++++++++++++++++++++++++++++++++++---- _tags | 20 ++++++++- lib/META | 4 +- lib/xenopsd.ml | 8 ++++ setup.ml | 20 +++++++-- 5 files changed, 156 insertions(+), 16 deletions(-) diff --git a/_oasis b/_oasis index 60af38763..fe248a48d 100644 --- a/_oasis +++ b/_oasis @@ -29,8 +29,53 @@ Library xenopsd Findlibname: xenopsd ByteOpt: -warn-error +a NativeOpt: -warn-error +a - Modules: Suspend_image, Cancellable_subprocess, Bootloader, Ionice, Mac, Xenops_migrate, Xenops_hooks, Task_server, Xenops_task, Updates, Xenops_utils, Xenops_server, Xenopsd, Xenops_server_plugin, Xenops_server_skeleton, Scheduler, Path, Storage, Interface, Xenctrl_uuid, Xenstore, Version - BuildDepends: threads, threads.posix, uuidm, xmlm, cohttp, uri, rpclib, rpclib.syntax, forkexec, fd-send-recv, xcp, xcp.xen, xcp.storage, sexplib, sexplib.syntax, xcp, uutf, xenstore, xenstore.unix, xenstore_transport, xenstore_transport.unix, oclock + Modules: + Suspend_image, + Cancellable_subprocess, + Bootloader, + Ionice, + Mac, + Xenops_migrate, + Xenops_hooks, + Task_server, + Xenops_task, + Updates, + Xenops_utils, + Xenops_server, + Xenopsd, + Xenops_server_plugin, + Xenops_server_skeleton, + Scheduler, + Path, + Storage, + Interface, + Xenctrl_uuid, + Xenstore, + Version + BuildDepends: + bisect_ppx, + threads, + threads.posix, + uuidm, + xmlm, + cohttp, + uri, + rpclib, + rpclib.syntax, + forkexec, + fd-send-recv, + xcp, + xcp.xen, + xcp.storage, + sexplib, + sexplib.syntax, + xcp, + uutf, + xenstore, + xenstore.unix, + xenstore_transport, + xenstore_transport.unix, + oclock CSources: sockopt_stubs.c Executable set_domain_uuid @@ -40,7 +85,11 @@ Executable set_domain_uuid NativeOpt: -warn-error +a-3 MainIs: set_domain_uuid.ml Install: false - BuildDepends: xenctrl, uuidm, cmdliner + BuildDepends: + bisect_ppx, + xenctrl, + uuidm, + cmdliner Executable suspend_image_viewer CompiledObject: best @@ -49,7 +98,10 @@ Executable suspend_image_viewer NativeOpt: -warn-error +a-3 MainIs: suspend_image_viewer.ml Install: false - BuildDepends: xenopsd, cmdliner + BuildDepends: + bisect_ppx, + xenopsd, + cmdliner Executable xenopsd_xc_main CompiledObject: best @@ -60,7 +112,23 @@ Executable xenopsd_xc_main Build$: flag(xen) Custom: true Install: false - BuildDepends: xenctrl, xenopsd, xenstore, xenstore.unix, xenstore_transport, xenstore_transport.unix, rpclib, forkexec, xcp, xcp.storage, xcp.memory, xcp.rrd, rrd, sexplib, xcp-inventory + BuildDepends: + bisect_ppx, + xenctrl, + xenopsd, + xenstore, + xenstore.unix, + xenstore_transport, + xenstore_transport.unix, + rpclib, + forkexec, + xcp, + xcp.storage, + xcp.memory, + xcp.rrd, + rrd, + sexplib, + xcp-inventory CSources: fsync_stubs.c, xenctrlext_stubs.c Executable watch_test @@ -70,7 +138,14 @@ Executable watch_test NativeOpt: -warn-error +a-3 MainIs: watch_test.ml Install: false - BuildDepends: xenopsd, xenstore, xenstore.unix, xenstore_transport, xenstore_transport.unix, threads + BuildDepends: + bisect_ppx, + xenopsd, + xenstore, + xenstore.unix, + xenstore_transport, + xenstore_transport.unix, + threads Executable xenopsd_simulator CompiledObject: best @@ -81,7 +156,9 @@ Executable xenopsd_simulator Build$: flag(simulator) Custom: true Install: false - BuildDepends: xenopsd + BuildDepends: + bisect_ppx, + xenopsd Executable xenopsd_libvirt_main CompiledObject: best @@ -92,7 +169,15 @@ Executable xenopsd_libvirt_main Build$: flag(libvirt) Custom: true Install: false - BuildDepends: xenopsd, rpclib, forkexec, xcp, xcp.storage, sexplib, libvirt + BuildDepends: + bisect_ppx, + xenopsd, + rpclib, + forkexec, + xcp, + xcp.storage, + sexplib, + libvirt Executable xenopsd_xenlight_main CompiledObject: best @@ -103,6 +188,23 @@ Executable xenopsd_xenlight_main Build$: flag(xenlight) Custom: true Install: false - BuildDepends: xenlight, xentoollog, xenctrl, xenopsd, xenstore, xenstore.unix, xenstore_transport, xenstore_transport.unix, rpclib, forkexec, xcp, xcp.storage, xcp.memory, sexplib, xcp-inventory, optcomp + BuildDepends: + bisect_ppx, + xenlight, + xentoollog, + xenctrl, + xenopsd, + xenstore, + xenstore.unix, + xenstore_transport, + xenstore_transport.unix, + rpclib, + forkexec, + xcp, + xcp.storage, + xcp.memory, + sexplib, + xcp-inventory, + optcomp CSources: fsync_stubs.c, poll_stubs.c diff --git a/_tags b/_tags index 96f920f2d..ed7239608 100644 --- a/_tags +++ b/_tags @@ -1,5 +1,5 @@ # OASIS_START -# DO NOT EDIT (digest: 76fa96e6edac33c29cf074bb5b0859c0) +# DO NOT EDIT (digest: bc2d8703604b2841004d3d8041cc1775) # Ignore VCS directories, you can use the same kind of rule outside # OASIS_START/STOP if you want to exclude directories that contains # useless stuff for the build process @@ -23,6 +23,7 @@ true: annot, bin_annot : oasis_library_xenopsd_native "lib/sockopt_stubs.c": oasis_library_xenopsd_native : use_libxenopsd_stubs +"lib/sockopt_stubs.c": pkg_bisect_ppx "lib/sockopt_stubs.c": pkg_cohttp "lib/sockopt_stubs.c": pkg_fd-send-recv "lib/sockopt_stubs.c": pkg_forkexec @@ -49,9 +50,11 @@ true: annot, bin_annot : oasis_executable_set_domain_uuid_byte : oasis_executable_set_domain_uuid_native : oasis_executable_set_domain_uuid_native +: pkg_bisect_ppx : pkg_cmdliner : pkg_uuidm : pkg_xenctrl +: pkg_bisect_ppx : pkg_cmdliner : pkg_uuidm : pkg_xenctrl @@ -60,6 +63,7 @@ true: annot, bin_annot : oasis_executable_suspend_image_viewer_byte : oasis_executable_suspend_image_viewer_native : oasis_executable_suspend_image_viewer_native +: pkg_bisect_ppx : pkg_cmdliner : pkg_cohttp : pkg_fd-send-recv @@ -83,6 +87,7 @@ true: annot, bin_annot : pkg_xenstore_transport.unix : pkg_xmlm : use_xenopsd +: pkg_bisect_ppx : pkg_cmdliner : pkg_cohttp : pkg_fd-send-recv @@ -116,6 +121,7 @@ true: annot, bin_annot "xc/fsync_stubs.c": oasis_executable_xenopsd_xc_main_native "xc/xenctrlext_stubs.c": oasis_executable_xenopsd_xc_main_native : use_libxenopsd_xc_main_stubs +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -148,6 +154,7 @@ true: annot, bin_annot : pkg_xcp.memory : pkg_xcp.rrd : pkg_xenctrl +"xc/fsync_stubs.c": pkg_bisect_ppx "xc/fsync_stubs.c": pkg_cohttp "xc/fsync_stubs.c": pkg_fd-send-recv "xc/fsync_stubs.c": pkg_forkexec @@ -175,6 +182,7 @@ true: annot, bin_annot "xc/fsync_stubs.c": pkg_xenstore_transport.unix "xc/fsync_stubs.c": pkg_xmlm "xc/fsync_stubs.c": use_xenopsd +"xc/xenctrlext_stubs.c": pkg_bisect_ppx "xc/xenctrlext_stubs.c": pkg_cohttp "xc/xenctrlext_stubs.c": pkg_fd-send-recv "xc/xenctrlext_stubs.c": pkg_forkexec @@ -208,6 +216,7 @@ true: annot, bin_annot : oasis_executable_watch_test_byte : oasis_executable_watch_test_native : oasis_executable_watch_test_native +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -230,6 +239,7 @@ true: annot, bin_annot : pkg_xenstore_transport.unix : pkg_xmlm : use_xenopsd +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -257,6 +267,7 @@ true: annot, bin_annot : oasis_executable_xenopsd_simulator_byte : oasis_executable_xenopsd_simulator_native : oasis_executable_xenopsd_simulator_native +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -279,6 +290,7 @@ true: annot, bin_annot : pkg_xenstore_transport.unix : pkg_xmlm : use_xenopsd +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -307,6 +319,7 @@ true: annot, bin_annot : oasis_executable_xenopsd_libvirt_main_byte : oasis_executable_xenopsd_libvirt_main_native : oasis_executable_xenopsd_libvirt_main_native +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -330,6 +343,7 @@ true: annot, bin_annot : pkg_xenstore_transport.unix : pkg_xmlm : use_xenopsd +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -364,6 +378,7 @@ true: annot, bin_annot "xl/fsync_stubs.c": oasis_executable_xenopsd_xenlight_main_native "xl/poll_stubs.c": oasis_executable_xenopsd_xenlight_main_native : use_libxenopsd_xenlight_main_stubs +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -392,6 +407,7 @@ true: annot, bin_annot : pkg_xentoollog : pkg_xmlm : use_xenopsd +: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -420,6 +436,7 @@ true: annot, bin_annot : pkg_xentoollog : pkg_xmlm : use_xenopsd +"xl/fsync_stubs.c": pkg_bisect_ppx "xl/fsync_stubs.c": pkg_cohttp "xl/fsync_stubs.c": pkg_fd-send-recv "xl/fsync_stubs.c": pkg_forkexec @@ -448,6 +465,7 @@ true: annot, bin_annot "xl/fsync_stubs.c": pkg_xentoollog "xl/fsync_stubs.c": pkg_xmlm "xl/fsync_stubs.c": use_xenopsd +"xl/poll_stubs.c": pkg_bisect_ppx "xl/poll_stubs.c": pkg_cohttp "xl/poll_stubs.c": pkg_fd-send-recv "xl/poll_stubs.c": pkg_forkexec diff --git a/lib/META b/lib/META index 9b2f4b2f5..179b09a33 100644 --- a/lib/META +++ b/lib/META @@ -1,9 +1,9 @@ # OASIS_START -# DO NOT EDIT (digest: 5586ee166df30de6e433138bcd3d4222) +# DO NOT EDIT (digest: 0a7a90b9f68d35d7f16b955e0a87a0b0) version = "0.12.0" description = "XenServer domain managers" requires = -"threads threads.posix uuidm xmlm cohttp uri rpclib rpclib.syntax forkexec fd-send-recv xcp xcp.xen xcp.storage sexplib sexplib.syntax xcp uutf xenstore xenstore.unix xenstore_transport xenstore_transport.unix oclock" +"bisect_ppx threads threads.posix uuidm xmlm cohttp uri rpclib rpclib.syntax forkexec fd-send-recv xcp xcp.xen xcp.storage sexplib sexplib.syntax xcp uutf xenstore xenstore.unix xenstore_transport xenstore_transport.unix oclock" archive(byte) = "xenopsd.cma" archive(byte, plugin) = "xenopsd.cma" archive(native) = "xenopsd.cmxa" diff --git a/lib/xenopsd.ml b/lib/xenopsd.ml index 2f6fcc461..46f14035c 100644 --- a/lib/xenopsd.ml +++ b/lib/xenopsd.ml @@ -133,9 +133,17 @@ let main backend = ~rpc_fn () in + (** we need to catch this to make sure at_exit handlers are + * triggered. In particuar, triggers for the bisect_ppx coverage + * profiling *) + + let signal_handler n = + debug "caught signal %d" n; exit 0 in + Xcp_service.maybe_daemonize (); Sys.set_signal Sys.sigpipe Sys.Signal_ignore; + Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler); Xenops_utils.set_fs_backend (Some (if !persist diff --git a/setup.ml b/setup.ml index 79fd3967e..502f0cbfe 100644 --- a/setup.ml +++ b/setup.ml @@ -1,7 +1,7 @@ (* setup.ml generated for the first time by OASIS v0.3.0 *) (* OASIS_START *) -(* DO NOT EDIT (digest: 6f6fe929d4b85590ded666e742264e21) *) +(* DO NOT EDIT (digest: 3e944b147adeba81cf228ee4c7f01eef) *) (* Regenerated by OASIS v0.4.5 Visit http://oasis.forge.ocamlcore.org for more information and @@ -6782,6 +6782,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); FindlibPackage ("threads", None); FindlibPackage ("threads.posix", None); FindlibPackage ("uuidm", None); @@ -6862,6 +6863,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); FindlibPackage ("xenctrl", None); FindlibPackage ("uuidm", None); FindlibPackage ("cmdliner", None) @@ -6892,6 +6894,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); InternalLibrary "xenopsd"; FindlibPackage ("cmdliner", None) ]; @@ -6928,6 +6931,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); FindlibPackage ("xenctrl", None); InternalLibrary "xenopsd"; FindlibPackage ("xenstore", None); @@ -6970,6 +6974,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); InternalLibrary "xenopsd"; FindlibPackage ("xenstore", None); FindlibPackage ("xenstore.unix", None); @@ -7005,7 +7010,11 @@ let setup_t = bs_install = [(OASISExpr.EBool true, false)]; bs_path = "simulator"; bs_compiled_object = Best; - bs_build_depends = [InternalLibrary "xenopsd"]; + bs_build_depends = + [ + FindlibPackage ("bisect_ppx", None); + InternalLibrary "xenopsd" + ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = []; bs_data_files = []; @@ -7039,6 +7048,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); InternalLibrary "xenopsd"; FindlibPackage ("rpclib", None); FindlibPackage ("forkexec", None); @@ -7080,6 +7090,7 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ + FindlibPackage ("bisect_ppx", None); FindlibPackage ("xenlight", None); FindlibPackage ("xentoollog", None); FindlibPackage ("xenctrl", None); @@ -7118,7 +7129,8 @@ let setup_t = }; oasis_fn = Some "_oasis"; oasis_version = "0.4.5"; - oasis_digest = Some "\024\144vQR\019\204K\197j+s\136\022\193}"; + oasis_digest = + Some "\169\019\155\1528\2274\199\183\007C\142\230\031\2419"; oasis_exec = None; oasis_setup_args = []; setup_update = false @@ -7126,6 +7138,6 @@ let setup_t = let setup () = BaseSetup.setup setup_t;; -# 7130 "setup.ml" +# 7142 "setup.ml" (* OASIS_STOP *) let () = setup ();; From c802c90f38d5fb86aae6644d47f4b769fba64045 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Wed, 11 May 2016 12:34:23 +0100 Subject: [PATCH 02/13] CP-17268 Updated opam file and README Since opam is not used to pull in all dependencies I'm not sure this opam file is working as intended. I've just added the biscec_ppx dependency. See the README for how to control where log data is written. Signed-off-by: Christian Lindig --- README.md | 19 +++++++++++++++++++ opam | 1 + 2 files changed, 20 insertions(+) diff --git a/README.md b/README.md index 8705734b0..716ee4c58 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,22 @@ xenopsd manages VMs running and provides a simple RPC control interface to the layer above (typically xapi). +## Coverage Profiling + +This branch adds coverage profiling with bisect_ppx. Binaries write +`bisect*.out` files, when they exit, to the current directory. These files +can be analysed with bisect-ppx-report: + + bisect-ppx-report -I _build -html coverage *.out + bisect-ppx-report -I _build -text coverage.txt *.out + +## Location of Profiling Data + +By default, an instrumented binary writes to `$CWD/bisect*.out`. In the +case of xenopsd in producion, this would be `/`. To avoid writing to `/` +and to avoid several services writing to the same place, start xenopsd +binaries with an evironment variable pointing to a better place: + + BISECT_FILE="/tmp/xenopsd-bisect" + + diff --git a/opam b/opam index b006e614c..cad612285 100644 --- a/opam +++ b/opam @@ -29,6 +29,7 @@ depends: [ "oclock" "xapi-inventory" "optcomp" + "bisect_ppx" ] depopts: "libvirt" {> "0.6.1.2"} ocaml-version: [>= "4.01.0"] From 9d7036e73ff42c562bbd1001d2324f3f4a4a7282 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Thu, 12 May 2016 11:03:38 +0100 Subject: [PATCH 03/13] CP-17268 sets xenopsd to log bisect files to tmp dir We don't want all log data to end up in / where others might log, too. This code finds a temp dir and directs bisect_ppx to log there. The BISECT_FILE env variable can still override this. Signed-off-by: Christian Lindig --- README.md | 4 ++-- lib/xenopsd.ml | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 716ee4c58..c63908245 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ and provides a simple RPC control interface to the layer above (typically xapi). ## Coverage Profiling This branch adds coverage profiling with bisect_ppx. Binaries write -`bisect*.out` files, when they exit, to the current directory. These files +`bisect*.out` files, when they exit to the current directory. These files can be analysed with bisect-ppx-report: bisect-ppx-report -I _build -html coverage *.out @@ -21,7 +21,7 @@ can be analysed with bisect-ppx-report: ## Location of Profiling Data By default, an instrumented binary writes to `$CWD/bisect*.out`. In the -case of xenopsd in producion, this would be `/`. To avoid writing to `/` +case of xenopsd in producition, this would be `/`. To avoid writing to `/` and to avoid several services writing to the same place, start xenopsd binaries with an evironment variable pointing to a better place: diff --git a/lib/xenopsd.ml b/lib/xenopsd.ml index 46f14035c..49350845d 100644 --- a/lib/xenopsd.ml +++ b/lib/xenopsd.ml @@ -58,6 +58,21 @@ let path () = Filename.concat !sockets_path "xenopsd" let forwarded_path () = path () ^ ".forwarded" (* receive an authenticated fd from xapi *) let json_path () = path () ^ ".json" +(** [tmpdir] holds the path to a directory for temporary files *) +let tmpdir = + let env n = try Sys.getenv n with Not_found -> "" in + let dirs = [env "TMP"; env "TEMP"; "/tmp"; "/usr/tmp"; "/var/tmp"] in + let is_dir = function + | "" -> false + | path -> try Sys.is_directory path with Sys_error _ -> false + in + try + List.find is_dir dirs + with + Not_found -> + error "can't find temp directory %s" __LOC__; + exit 1 + module Server = Xenops_interface.Server(Xenops_server) let rpc_fn call = @@ -99,6 +114,8 @@ let doc = String.concat "\n" [ "Xenopsd looks after a set of Xen domains, performing lifecycle operations including start/shutdown/migrate. A system may run multiple xenopsds, each looking after a different set of VMs. Xenopsd will always ignore domains that it hasn't been asked to manage. There are multiple xenopsd *backends*, including 'xc': which uses libxc directly and 'xenlight': which uses the new Xen libxl library (recommended)."; ] + + let configure ?(specific_options=[]) ?(specific_essential_paths=[]) ?(specific_nonessential_paths=[]) () = Debug.set_facility Syslog.Local5; @@ -117,6 +134,16 @@ let configure ?(specific_options=[]) ?(specific_essential_paths=[]) ?(specific_n error "%s" m; exit 1 +(** set up the BISECT_FILE env var to point to a temp directory where + * the log files go + *) +let setup_bisect () = + let (//) = Filename.concat in + try + ignore (Sys.getenv "BISECT_FILE") + with Not_found -> + Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s" name) + let main backend = Printexc.record_backtrace true; @@ -144,6 +171,8 @@ let main backend = Sys.set_signal Sys.sigpipe Sys.Signal_ignore; Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler); + + setup_bisect (); (* coverage profiling *) Xenops_utils.set_fs_backend (Some (if !persist From 82a893093b053a9a57b26425a99745363e3197d1 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Thu, 12 May 2016 11:25:22 +0100 Subject: [PATCH 04/13] CP-17268 combine all setup code for bisect_ppx into one function Signed-off-by: Christian Lindig --- lib/xenopsd.ml | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/xenopsd.ml b/lib/xenopsd.ml index 49350845d..6b6af73ee 100644 --- a/lib/xenopsd.ml +++ b/lib/xenopsd.ml @@ -58,21 +58,7 @@ let path () = Filename.concat !sockets_path "xenopsd" let forwarded_path () = path () ^ ".forwarded" (* receive an authenticated fd from xapi *) let json_path () = path () ^ ".json" -(** [tmpdir] holds the path to a directory for temporary files *) -let tmpdir = - let env n = try Sys.getenv n with Not_found -> "" in - let dirs = [env "TMP"; env "TEMP"; "/tmp"; "/usr/tmp"; "/var/tmp"] in - let is_dir = function - | "" -> false - | path -> try Sys.is_directory path with Sys_error _ -> false - in - try - List.find is_dir dirs - with - Not_found -> - error "can't find temp directory %s" __LOC__; - exit 1 - + module Server = Xenops_interface.Server(Xenops_server) let rpc_fn call = @@ -137,9 +123,25 @@ let configure ?(specific_options=[]) ?(specific_essential_paths=[]) ?(specific_n (** set up the BISECT_FILE env var to point to a temp directory where * the log files go *) -let setup_bisect () = +let setup_bisect name = let (//) = Filename.concat in - try + let tmpdir = + let getenv n = try Sys.getenv n with Not_found -> "" in + let dirs = + [ getenv "TMP" + ; getenv "TEMP" + ; "/tmp" + ; "/usr/tmp" + ; "/var/tmp" + ] in + let is_dir = function + | "" -> false + | path -> try Sys.is_directory path with Sys_error _ -> false + in try + List.find is_dir dirs + with + Not_found -> error "can't find temp directory %s" __LOC__; exit 1 + in try ignore (Sys.getenv "BISECT_FILE") with Not_found -> Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s" name) @@ -172,7 +174,7 @@ let main backend = Sys.set_signal Sys.sigpipe Sys.Signal_ignore; Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler); - setup_bisect (); (* coverage profiling *) + setup_bisect name; (* set up coverage profiling *) Xenops_utils.set_fs_backend (Some (if !persist From 143ce014de918b95ec44e09148b9abf67fbd2b4c Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Thu, 12 May 2016 11:34:25 +0100 Subject: [PATCH 05/13] CP-17268 move bisect setup code into a module of its own We need this code for the other binaries in this repo, too. Hence, it better lives in its own module Signed-off-by: Christian Lindig --- lib/bisect_setup.ml | 29 +++++++++++++++++++++++++++++ lib/xenopsd.ml | 29 ++--------------------------- 2 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 lib/bisect_setup.ml diff --git a/lib/bisect_setup.ml b/lib/bisect_setup.ml new file mode 100644 index 000000000..29bce9d29 --- /dev/null +++ b/lib/bisect_setup.ml @@ -0,0 +1,29 @@ +(** set up the BISECT_FILE env var to point to a temp directory where + * the log files go + *) + +module D = Debug.Make(struct let name = "bisect_setup" end) + +let init name = + let (//) = Filename.concat in + let tmpdir = + let getenv n = try Sys.getenv n with Not_found -> "" in + let dirs = + [ getenv "TMP" + ; getenv "TEMP" + ; "/tmp" + ; "/usr/tmp" + ; "/var/tmp" + ] in + let is_dir = function + | "" -> false + | path -> try Sys.is_directory path with Sys_error _ -> false + in try + List.find is_dir dirs + with + Not_found -> D.error "can't find temp directory %s" __LOC__; exit 1 + in try + ignore (Sys.getenv "BISECT_FILE") + with Not_found -> + Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s" name) + diff --git a/lib/xenopsd.ml b/lib/xenopsd.ml index 6b6af73ee..a8adac48d 100644 --- a/lib/xenopsd.ml +++ b/lib/xenopsd.ml @@ -120,32 +120,7 @@ let configure ?(specific_options=[]) ?(specific_essential_paths=[]) ?(specific_n error "%s" m; exit 1 -(** set up the BISECT_FILE env var to point to a temp directory where - * the log files go - *) -let setup_bisect name = - let (//) = Filename.concat in - let tmpdir = - let getenv n = try Sys.getenv n with Not_found -> "" in - let dirs = - [ getenv "TMP" - ; getenv "TEMP" - ; "/tmp" - ; "/usr/tmp" - ; "/var/tmp" - ] in - let is_dir = function - | "" -> false - | path -> try Sys.is_directory path with Sys_error _ -> false - in try - List.find is_dir dirs - with - Not_found -> error "can't find temp directory %s" __LOC__; exit 1 - in try - ignore (Sys.getenv "BISECT_FILE") - with Not_found -> - Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s" name) - + let main backend = Printexc.record_backtrace true; @@ -174,7 +149,7 @@ let main backend = Sys.set_signal Sys.sigpipe Sys.Signal_ignore; Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler); - setup_bisect name; (* set up coverage profiling *) + Bisect_setup.init name; (* set up coverage profiling *) Xenops_utils.set_fs_backend (Some (if !persist From 7a25ada4ba3b17149cba1e4f19213d15f379a96f Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Thu, 12 May 2016 16:36:31 +0100 Subject: [PATCH 06/13] CP-17268 Updated README re where log files are written Signed-off-by: Christian Lindig --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c63908245..f12505f7b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ case of xenopsd in producition, this would be `/`. To avoid writing to `/` and to avoid several services writing to the same place, start xenopsd binaries with an evironment variable pointing to a better place: - BISECT_FILE="/tmp/xenopsd-bisect" + BISECT_FILE="/tmp/bisect-xenopsd" + +Function `Bisect_setup.init name` sets the environment variable if it is +unset from inside the program such that log data is written to the temp +directory (repecting TMP and TEMP env vars id set). However, logging to +$CWD will still work even if the `init` function is not called. + From 8a9dbc3157a8dc437e8eeef1253731a87f14e52c Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Mon, 16 May 2016 11:00:04 +0100 Subject: [PATCH 07/13] CP-17268 cleaner integrates coverage profiling: make coverage To set up a build for coverage profiling, use "make coverage" followed by "make". This should it make possible to interate this code into the main line. Supporting code lives in profiling/. All other changes to the code are concerned with better signal handling and should likewise go into the main line. Signed-off-by: Christian Lindig --- COVERAGE.md | 45 +++++++++ Makefile | 16 +++ README.md | 2 +- _oasis | 39 +++++--- _tags | 45 +++++---- _tags.coverage | 6 ++ lib/META | 4 +- lib/bisect_setup.ml | 29 ------ lib/xenopsd.ml | 2 +- myocamlbuild.ml | 187 +++++++++++++++++++++++++++++++++--- profiling/META | 11 +++ profiling/_oasis | 10 ++ profiling/coverage.ml | 35 +++++++ profiling/coverage.mldylib | 4 + profiling/coverage.mli | 7 ++ profiling/coverage.mllib | 4 + profiling/profiling.mldylib | 4 + profiling/profiling.mllib | 4 + setup.ml | 128 ++++++++++++++++-------- xc/xenops_xc_main.ml | 1 + 20 files changed, 466 insertions(+), 117 deletions(-) create mode 100644 COVERAGE.md create mode 100644 _tags.coverage delete mode 100644 lib/bisect_setup.ml create mode 100644 profiling/META create mode 100644 profiling/_oasis create mode 100644 profiling/coverage.ml create mode 100644 profiling/coverage.mldylib create mode 100644 profiling/coverage.mli create mode 100644 profiling/coverage.mllib create mode 100644 profiling/profiling.mldylib create mode 100644 profiling/profiling.mllib diff --git a/COVERAGE.md b/COVERAGE.md new file mode 100644 index 000000000..ed8673b1f --- /dev/null +++ b/COVERAGE.md @@ -0,0 +1,45 @@ + +# Coverage Analysis + +This project can be compiled for coverage analysis using [bisect_ppx]. By +default, this is not done. To compile for coverage analysis, do: + + make coverage + make + +The `coverage` target adds the rules in `_tags.coverage` to the `_tags` +file, which in turn causes all code to be compiled for coverage +analysis. The `_tags.coverage` file could be tweaked to control which +files get instrumented. + +## Support Files + +See [profiling/coverage.ml](./profiling/coverage.ml) for the run-time +setup of coverage profiling. This code has no effect when not profiling +during execution. Once [bixect_ppx] has better defaults we could get rid +of it. + +## Execution and Logging + +During program execution, a binary writes coverage data to + + /tmp/bisect-lunarossa-*.out + +This can be overridden by setting the `BISECT_FILE` environment +variable, which is otherwise set at startup using the code in +`profiling/coverage.ml`; + +## Analysis + +See the [bisect_ppx] documentation for details but try from the +top-level directory: + + bisect-ppx-report -I _build -html coverage /tmp/bisect-*.out + +This creates an HTML document in [coverage/](./coverage]. + +[bisect_ppx]: https://github.com/aantron/bisect_ppx + + + + diff --git a/Makefile b/Makefile index ef55f7739..67f2275e5 100644 --- a/Makefile +++ b/Makefile @@ -97,3 +97,19 @@ release: grep -v 'warn-error' _oasis > _oasis.tmp mv _oasis.tmp _oasis oasis setup + +# make coverage +# prepares for building with coverage analysis +# +# make uncover +# reverses the setup from "make coverage" + +coverage: _tags _tags.coverage + test ! -f _tags.orig && mv _tags _tags.orig || true + cat _tags.coverage _tags.orig > _tags + +uncover: _tags.orig + mv _tags.orig _tags + +.PHONY: default coverage uncover + diff --git a/README.md b/README.md index f12505f7b..355ddfc91 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ binaries with an evironment variable pointing to a better place: Function `Bisect_setup.init name` sets the environment variable if it is unset from inside the program such that log data is written to the temp -directory (repecting TMP and TEMP env vars id set). However, logging to +directory (respecting TMP and TEMP env vars if set). However, logging to $CWD will still work even if the `init` function is not called. diff --git a/_oasis b/_oasis index fe248a48d..bcdb75f45 100644 --- a/_oasis +++ b/_oasis @@ -23,6 +23,16 @@ Flag simulator Description: Build server with simulator support Default: true + +# Support files for profiling +Library profiling + CompiledObject: best + Path: profiling + Install: false + Findlibname: profiling + Modules: Coverage + BuildDepends: + Library xenopsd CompiledObject: best Path: lib @@ -53,7 +63,6 @@ Library xenopsd Xenstore, Version BuildDepends: - bisect_ppx, threads, threads.posix, uuidm, @@ -86,10 +95,10 @@ Executable set_domain_uuid MainIs: set_domain_uuid.ml Install: false BuildDepends: - bisect_ppx, xenctrl, uuidm, - cmdliner + cmdliner, + profiling Executable suspend_image_viewer CompiledObject: best @@ -99,9 +108,9 @@ Executable suspend_image_viewer MainIs: suspend_image_viewer.ml Install: false BuildDepends: - bisect_ppx, xenopsd, - cmdliner + cmdliner, + profiling Executable xenopsd_xc_main CompiledObject: best @@ -113,7 +122,6 @@ Executable xenopsd_xc_main Custom: true Install: false BuildDepends: - bisect_ppx, xenctrl, xenopsd, xenstore, @@ -128,7 +136,8 @@ Executable xenopsd_xc_main xcp.rrd, rrd, sexplib, - xcp-inventory + xcp-inventory, + profiling CSources: fsync_stubs.c, xenctrlext_stubs.c Executable watch_test @@ -139,13 +148,13 @@ Executable watch_test MainIs: watch_test.ml Install: false BuildDepends: - bisect_ppx, xenopsd, xenstore, xenstore.unix, xenstore_transport, xenstore_transport.unix, - threads + threads, + profiling Executable xenopsd_simulator CompiledObject: best @@ -157,8 +166,8 @@ Executable xenopsd_simulator Custom: true Install: false BuildDepends: - bisect_ppx, - xenopsd + xenopsd, + profiling Executable xenopsd_libvirt_main CompiledObject: best @@ -170,14 +179,14 @@ Executable xenopsd_libvirt_main Custom: true Install: false BuildDepends: - bisect_ppx, xenopsd, rpclib, forkexec, xcp, xcp.storage, sexplib, - libvirt + libvirt, + profiling Executable xenopsd_xenlight_main CompiledObject: best @@ -189,7 +198,6 @@ Executable xenopsd_xenlight_main Custom: true Install: false BuildDepends: - bisect_ppx, xenlight, xentoollog, xenctrl, @@ -205,6 +213,7 @@ Executable xenopsd_xenlight_main xcp.memory, sexplib, xcp-inventory, - optcomp + optcomp, + profiling CSources: fsync_stubs.c, poll_stubs.c diff --git a/_tags b/_tags index ed7239608..597f6854b 100644 --- a/_tags +++ b/_tags @@ -1,5 +1,11 @@ +# START_COVERAGE +# coverage analysis with bisect_ppx +# compile and link with package bisect_ppx +<**/*.ml{,i,y}>: pkg_bisect_ppx +<**/*.native>: pkg_bisect_ppx +# END_COVERAGE # OASIS_START -# DO NOT EDIT (digest: bc2d8703604b2841004d3d8041cc1775) +# DO NOT EDIT (digest: 75c8d08bbb53d180415f0183181b9cf1) # Ignore VCS directories, you can use the same kind of rule outside # OASIS_START/STOP if you want to exclude directories that contains # useless stuff for the build process @@ -14,6 +20,8 @@ true: annot, bin_annot ".git": not_hygienic "_darcs": -traverse "_darcs": not_hygienic +# Library profiling +"profiling/profiling.cmxs": use_profiling # Library xenopsd "lib/xenopsd.cmxs": use_xenopsd : oasis_library_xenopsd_byte @@ -23,7 +31,6 @@ true: annot, bin_annot : oasis_library_xenopsd_native "lib/sockopt_stubs.c": oasis_library_xenopsd_native : use_libxenopsd_stubs -"lib/sockopt_stubs.c": pkg_bisect_ppx "lib/sockopt_stubs.c": pkg_cohttp "lib/sockopt_stubs.c": pkg_fd-send-recv "lib/sockopt_stubs.c": pkg_forkexec @@ -50,20 +57,19 @@ true: annot, bin_annot : oasis_executable_set_domain_uuid_byte : oasis_executable_set_domain_uuid_native : oasis_executable_set_domain_uuid_native -: pkg_bisect_ppx : pkg_cmdliner : pkg_uuidm : pkg_xenctrl -: pkg_bisect_ppx +: use_profiling : pkg_cmdliner : pkg_uuidm : pkg_xenctrl +: use_profiling # Executable suspend_image_viewer : oasis_executable_suspend_image_viewer_byte : oasis_executable_suspend_image_viewer_byte : oasis_executable_suspend_image_viewer_native : oasis_executable_suspend_image_viewer_native -: pkg_bisect_ppx : pkg_cmdliner : pkg_cohttp : pkg_fd-send-recv @@ -86,8 +92,8 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd -: pkg_bisect_ppx : pkg_cmdliner : pkg_cohttp : pkg_fd-send-recv @@ -110,6 +116,7 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd # Executable xenopsd_xc_main : oasis_executable_xenopsd_xc_main_byte @@ -121,7 +128,6 @@ true: annot, bin_annot "xc/fsync_stubs.c": oasis_executable_xenopsd_xc_main_native "xc/xenctrlext_stubs.c": oasis_executable_xenopsd_xc_main_native : use_libxenopsd_xc_main_stubs -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -148,13 +154,13 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd : pkg_rrd : pkg_xcp-inventory : pkg_xcp.memory : pkg_xcp.rrd : pkg_xenctrl -"xc/fsync_stubs.c": pkg_bisect_ppx "xc/fsync_stubs.c": pkg_cohttp "xc/fsync_stubs.c": pkg_fd-send-recv "xc/fsync_stubs.c": pkg_forkexec @@ -181,8 +187,8 @@ true: annot, bin_annot "xc/fsync_stubs.c": pkg_xenstore_transport "xc/fsync_stubs.c": pkg_xenstore_transport.unix "xc/fsync_stubs.c": pkg_xmlm +"xc/fsync_stubs.c": use_profiling "xc/fsync_stubs.c": use_xenopsd -"xc/xenctrlext_stubs.c": pkg_bisect_ppx "xc/xenctrlext_stubs.c": pkg_cohttp "xc/xenctrlext_stubs.c": pkg_fd-send-recv "xc/xenctrlext_stubs.c": pkg_forkexec @@ -209,6 +215,7 @@ true: annot, bin_annot "xc/xenctrlext_stubs.c": pkg_xenstore_transport "xc/xenctrlext_stubs.c": pkg_xenstore_transport.unix "xc/xenctrlext_stubs.c": pkg_xmlm +"xc/xenctrlext_stubs.c": use_profiling "xc/xenctrlext_stubs.c": use_xenopsd : custom # Executable watch_test @@ -216,7 +223,6 @@ true: annot, bin_annot : oasis_executable_watch_test_byte : oasis_executable_watch_test_native : oasis_executable_watch_test_native -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -238,8 +244,8 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -261,13 +267,13 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd # Executable xenopsd_simulator : oasis_executable_xenopsd_simulator_byte : oasis_executable_xenopsd_simulator_byte : oasis_executable_xenopsd_simulator_native : oasis_executable_xenopsd_simulator_native -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -289,8 +295,8 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -312,6 +318,7 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd : custom # Executable xenopsd_libvirt_main @@ -319,7 +326,6 @@ true: annot, bin_annot : oasis_executable_xenopsd_libvirt_main_byte : oasis_executable_xenopsd_libvirt_main_native : oasis_executable_xenopsd_libvirt_main_native -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -342,8 +348,8 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -366,6 +372,7 @@ true: annot, bin_annot : pkg_xenstore_transport : pkg_xenstore_transport.unix : pkg_xmlm +: use_profiling : use_xenopsd : custom # Executable xenopsd_xenlight_main @@ -378,7 +385,6 @@ true: annot, bin_annot "xl/fsync_stubs.c": oasis_executable_xenopsd_xenlight_main_native "xl/poll_stubs.c": oasis_executable_xenopsd_xenlight_main_native : use_libxenopsd_xenlight_main_stubs -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -406,8 +412,8 @@ true: annot, bin_annot : pkg_xenstore_transport.unix : pkg_xentoollog : pkg_xmlm +: use_profiling : use_xenopsd -: pkg_bisect_ppx : pkg_cohttp : pkg_fd-send-recv : pkg_forkexec @@ -435,8 +441,8 @@ true: annot, bin_annot : pkg_xenstore_transport.unix : pkg_xentoollog : pkg_xmlm +: use_profiling : use_xenopsd -"xl/fsync_stubs.c": pkg_bisect_ppx "xl/fsync_stubs.c": pkg_cohttp "xl/fsync_stubs.c": pkg_fd-send-recv "xl/fsync_stubs.c": pkg_forkexec @@ -464,8 +470,8 @@ true: annot, bin_annot "xl/fsync_stubs.c": pkg_xenstore_transport.unix "xl/fsync_stubs.c": pkg_xentoollog "xl/fsync_stubs.c": pkg_xmlm +"xl/fsync_stubs.c": use_profiling "xl/fsync_stubs.c": use_xenopsd -"xl/poll_stubs.c": pkg_bisect_ppx "xl/poll_stubs.c": pkg_cohttp "xl/poll_stubs.c": pkg_fd-send-recv "xl/poll_stubs.c": pkg_forkexec @@ -493,6 +499,7 @@ true: annot, bin_annot "xl/poll_stubs.c": pkg_xenstore_transport.unix "xl/poll_stubs.c": pkg_xentoollog "xl/poll_stubs.c": pkg_xmlm +"xl/poll_stubs.c": use_profiling "xl/poll_stubs.c": use_xenopsd : custom # OASIS_STOP diff --git a/_tags.coverage b/_tags.coverage new file mode 100644 index 000000000..8c543834f --- /dev/null +++ b/_tags.coverage @@ -0,0 +1,6 @@ +# START_COVERAGE +# coverage analysis with bisect_ppx +# compile and link with package bisect_ppx +<**/*.ml{,i,y}>: pkg_bisect_ppx +<**/*.native>: pkg_bisect_ppx +# END_COVERAGE diff --git a/lib/META b/lib/META index 179b09a33..9b2f4b2f5 100644 --- a/lib/META +++ b/lib/META @@ -1,9 +1,9 @@ # OASIS_START -# DO NOT EDIT (digest: 0a7a90b9f68d35d7f16b955e0a87a0b0) +# DO NOT EDIT (digest: 5586ee166df30de6e433138bcd3d4222) version = "0.12.0" description = "XenServer domain managers" requires = -"bisect_ppx threads threads.posix uuidm xmlm cohttp uri rpclib rpclib.syntax forkexec fd-send-recv xcp xcp.xen xcp.storage sexplib sexplib.syntax xcp uutf xenstore xenstore.unix xenstore_transport xenstore_transport.unix oclock" +"threads threads.posix uuidm xmlm cohttp uri rpclib rpclib.syntax forkexec fd-send-recv xcp xcp.xen xcp.storage sexplib sexplib.syntax xcp uutf xenstore xenstore.unix xenstore_transport xenstore_transport.unix oclock" archive(byte) = "xenopsd.cma" archive(byte, plugin) = "xenopsd.cma" archive(native) = "xenopsd.cmxa" diff --git a/lib/bisect_setup.ml b/lib/bisect_setup.ml deleted file mode 100644 index 29bce9d29..000000000 --- a/lib/bisect_setup.ml +++ /dev/null @@ -1,29 +0,0 @@ -(** set up the BISECT_FILE env var to point to a temp directory where - * the log files go - *) - -module D = Debug.Make(struct let name = "bisect_setup" end) - -let init name = - let (//) = Filename.concat in - let tmpdir = - let getenv n = try Sys.getenv n with Not_found -> "" in - let dirs = - [ getenv "TMP" - ; getenv "TEMP" - ; "/tmp" - ; "/usr/tmp" - ; "/var/tmp" - ] in - let is_dir = function - | "" -> false - | path -> try Sys.is_directory path with Sys_error _ -> false - in try - List.find is_dir dirs - with - Not_found -> D.error "can't find temp directory %s" __LOC__; exit 1 - in try - ignore (Sys.getenv "BISECT_FILE") - with Not_found -> - Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s" name) - diff --git a/lib/xenopsd.ml b/lib/xenopsd.ml index a8adac48d..7e9c911c8 100644 --- a/lib/xenopsd.ml +++ b/lib/xenopsd.ml @@ -149,7 +149,7 @@ let main backend = Sys.set_signal Sys.sigpipe Sys.Signal_ignore; Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler); - Bisect_setup.init name; (* set up coverage profiling *) + Coverage.init name; (* set up coverage profiling *) Xenops_utils.set_fs_backend (Some (if !persist diff --git a/myocamlbuild.ml b/myocamlbuild.ml index 9b12a1af5..4c83bd4d9 100644 --- a/myocamlbuild.ml +++ b/myocamlbuild.ml @@ -1,5 +1,5 @@ (* OASIS_START *) -(* DO NOT EDIT (digest: c4687943ad9b35db36fce435aeae72fd) *) +(* DO NOT EDIT (digest: 28a98a80b057607577ddf2e46a295148) *) module OASISGettext = struct (* # 22 "src/oasis/OASISGettext.ml" *) @@ -29,6 +29,166 @@ module OASISGettext = struct end +module OASISString = struct +(* # 22 "src/oasis/OASISString.ml" *) + + + (** Various string utilities. + + Mostly inspired by extlib and batteries ExtString and BatString libraries. + + @author Sylvain Le Gall + *) + + + let nsplitf str f = + if str = "" then + [] + else + let buf = Buffer.create 13 in + let lst = ref [] in + let push () = + lst := Buffer.contents buf :: !lst; + Buffer.clear buf + in + let str_len = String.length str in + for i = 0 to str_len - 1 do + if f str.[i] then + push () + else + Buffer.add_char buf str.[i] + done; + push (); + List.rev !lst + + + (** [nsplit c s] Split the string [s] at char [c]. It doesn't include the + separator. + *) + let nsplit str c = + nsplitf str ((=) c) + + + let find ~what ?(offset=0) str = + let what_idx = ref 0 in + let str_idx = ref offset in + while !str_idx < String.length str && + !what_idx < String.length what do + if str.[!str_idx] = what.[!what_idx] then + incr what_idx + else + what_idx := 0; + incr str_idx + done; + if !what_idx <> String.length what then + raise Not_found + else + !str_idx - !what_idx + + + let sub_start str len = + let str_len = String.length str in + if len >= str_len then + "" + else + String.sub str len (str_len - len) + + + let sub_end ?(offset=0) str len = + let str_len = String.length str in + if len >= str_len then + "" + else + String.sub str 0 (str_len - len) + + + let starts_with ~what ?(offset=0) str = + let what_idx = ref 0 in + let str_idx = ref offset in + let ok = ref true in + while !ok && + !str_idx < String.length str && + !what_idx < String.length what do + if str.[!str_idx] = what.[!what_idx] then + incr what_idx + else + ok := false; + incr str_idx + done; + if !what_idx = String.length what then + true + else + false + + + let strip_starts_with ~what str = + if starts_with ~what str then + sub_start str (String.length what) + else + raise Not_found + + + let ends_with ~what ?(offset=0) str = + let what_idx = ref ((String.length what) - 1) in + let str_idx = ref ((String.length str) - 1) in + let ok = ref true in + while !ok && + offset <= !str_idx && + 0 <= !what_idx do + if str.[!str_idx] = what.[!what_idx] then + decr what_idx + else + ok := false; + decr str_idx + done; + if !what_idx = -1 then + true + else + false + + + let strip_ends_with ~what str = + if ends_with ~what str then + sub_end str (String.length what) + else + raise Not_found + + + let replace_chars f s = + let buf = Buffer.create (String.length s) in + String.iter (fun c -> Buffer.add_char buf (f c)) s; + Buffer.contents buf + + let lowercase_ascii = + replace_chars + (fun c -> + if (c >= 'A' && c <= 'Z') then + Char.chr (Char.code c + 32) + else + c) + + let uncapitalize_ascii s = + if s <> "" then + (lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1)) + else + s + + let uppercase_ascii = + replace_chars + (fun c -> + if (c >= 'a' && c <= 'z') then + Char.chr (Char.code c - 32) + else + c) + + let capitalize_ascii s = + if s <> "" then + (uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1)) + else + s + +end + module OASISExpr = struct (* # 22 "src/oasis/OASISExpr.ml" *) @@ -129,7 +289,7 @@ module OASISExpr = struct end -# 132 "myocamlbuild.ml" +# 292 "myocamlbuild.ml" module BaseEnvLight = struct (* # 22 "src/base/BaseEnvLight.ml" *) @@ -234,7 +394,7 @@ module BaseEnvLight = struct end -# 237 "myocamlbuild.ml" +# 397 "myocamlbuild.ml" module MyOCamlbuildFindlib = struct (* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *) @@ -516,7 +676,7 @@ module MyOCamlbuildBase = struct | nm, [], intf_modules -> ocaml_lib nm; let cmis = - List.map (fun m -> (String.uncapitalize m) ^ ".cmi") + List.map (fun m -> (OASISString.uncapitalize_ascii m) ^ ".cmi") intf_modules in dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis | nm, dir :: tl, intf_modules -> @@ -529,7 +689,7 @@ module MyOCamlbuildBase = struct ["compile"; "infer_interface"; "doc"]) tl; let cmis = - List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi") + List.map (fun m -> dir^"/"^(OASISString.uncapitalize_ascii m)^".cmi") intf_modules in dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"] cmis) @@ -603,11 +763,12 @@ module MyOCamlbuildBase = struct end -# 606 "myocamlbuild.ml" +# 766 "myocamlbuild.ml" open Ocamlbuild_plugin;; let package_default = { - MyOCamlbuildBase.lib_ocaml = [("xenopsd", ["lib"], [])]; + MyOCamlbuildBase.lib_ocaml = + [("profiling", ["profiling"], []); ("xenopsd", ["lib"], [])]; lib_c = [ ("xenopsd", "lib", []); @@ -895,10 +1056,12 @@ let package_default = ]; includes = [ - ("xl", ["lib"]); - ("xc", ["lib"]); - ("simulator", ["lib"]); - ("libvirt", ["lib"]) + ("xl", ["lib"; "profiling"]); + ("xc", ["lib"; "profiling"]); + ("tools", ["profiling"]); + ("simulator", ["lib"; "profiling"]); + ("libvirt", ["lib"; "profiling"]); + ("lib", ["profiling"]) ] } ;; @@ -907,6 +1070,6 @@ let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false} let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;; -# 911 "myocamlbuild.ml" +# 1074 "myocamlbuild.ml" (* OASIS_STOP *) Ocamlbuild_plugin.dispatch dispatch_default;; diff --git a/profiling/META b/profiling/META new file mode 100644 index 000000000..08ba5f0dd --- /dev/null +++ b/profiling/META @@ -0,0 +1,11 @@ +# OASIS_START +# DO NOT EDIT (digest: ee7e3fdd2b390090469a9e871a315e9c) +version = "0.12.0" +description = "XenServer domain managers" +archive(byte) = "profiling.cma" +archive(byte, plugin) = "profiling.cma" +archive(native) = "profiling.cmxa" +archive(native, plugin) = "profiling.cmxs" +exists_if = "profiling.cma" +# OASIS_STOP + diff --git a/profiling/_oasis b/profiling/_oasis new file mode 100644 index 000000000..ae4677bb7 --- /dev/null +++ b/profiling/_oasis @@ -0,0 +1,10 @@ + +# Support files for coverage profiling +Library coverage + CompiledObject: best + Path: profiling + Findlibname: coverage + Modules: Coverage + BuildDepends: + + diff --git a/profiling/coverage.ml b/profiling/coverage.ml new file mode 100644 index 000000000..adc136a55 --- /dev/null +++ b/profiling/coverage.ml @@ -0,0 +1,35 @@ + +(** This module sets up the env variable for bisect_ppx which describes + * where log files are writte + *) + +let (//) = Filename.concat + +let is_dir = function + | "" -> false + | path -> try Sys.is_directory path with Sys_error _ -> false + +(* [tmpdir] points to a directory for temporary files *) +let tmpdir = + let getenv n = try Sys.getenv n with Not_found -> "" in + let dirs = + [ getenv "TMP" + ; getenv "TEMP" + ; "/tmp" + ; "/usr/tmp" + ; "/var/tmp" + ] in + try + List.find is_dir dirs + with + Not_found -> failwith "can't find temp directory "^__LOC__ + +(** [init name] sets up coverage profiling for binary [name]. You could + * use [Sys.argv.(0) for name + *) +let init name = + try + ignore (Sys.getenv "BISECT_FILE") + with Not_found -> + Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s-" name) + diff --git a/profiling/coverage.mldylib b/profiling/coverage.mldylib new file mode 100644 index 000000000..2c6e555c2 --- /dev/null +++ b/profiling/coverage.mldylib @@ -0,0 +1,4 @@ +# OASIS_START +# DO NOT EDIT (digest: 9841bdc50c4226cb6ec5db76494249e6) +Coverage +# OASIS_STOP diff --git a/profiling/coverage.mli b/profiling/coverage.mli new file mode 100644 index 000000000..f9a84b34e --- /dev/null +++ b/profiling/coverage.mli @@ -0,0 +1,7 @@ + + +(** [init name] sets up coverage profiling for binary [name]. You could + * use [Sys.argv.(0) for name + *) + +val init: string -> unit diff --git a/profiling/coverage.mllib b/profiling/coverage.mllib new file mode 100644 index 000000000..2c6e555c2 --- /dev/null +++ b/profiling/coverage.mllib @@ -0,0 +1,4 @@ +# OASIS_START +# DO NOT EDIT (digest: 9841bdc50c4226cb6ec5db76494249e6) +Coverage +# OASIS_STOP diff --git a/profiling/profiling.mldylib b/profiling/profiling.mldylib new file mode 100644 index 000000000..2c6e555c2 --- /dev/null +++ b/profiling/profiling.mldylib @@ -0,0 +1,4 @@ +# OASIS_START +# DO NOT EDIT (digest: 9841bdc50c4226cb6ec5db76494249e6) +Coverage +# OASIS_STOP diff --git a/profiling/profiling.mllib b/profiling/profiling.mllib new file mode 100644 index 000000000..2c6e555c2 --- /dev/null +++ b/profiling/profiling.mllib @@ -0,0 +1,4 @@ +# OASIS_START +# DO NOT EDIT (digest: 9841bdc50c4226cb6ec5db76494249e6) +Coverage +# OASIS_STOP diff --git a/setup.ml b/setup.ml index 502f0cbfe..f971f1f9e 100644 --- a/setup.ml +++ b/setup.ml @@ -1,9 +1,9 @@ (* setup.ml generated for the first time by OASIS v0.3.0 *) (* OASIS_START *) -(* DO NOT EDIT (digest: 3e944b147adeba81cf228ee4c7f01eef) *) +(* DO NOT EDIT (digest: a35c6712bc4eeadb8afbb52bb7533da3) *) (* - Regenerated by OASIS v0.4.5 + Regenerated by OASIS v0.4.6 Visit http://oasis.forge.ocamlcore.org for more information and documentation about functions used in this file. *) @@ -246,6 +246,33 @@ module OASISString = struct String.iter (fun c -> Buffer.add_char buf (f c)) s; Buffer.contents buf + let lowercase_ascii = + replace_chars + (fun c -> + if (c >= 'A' && c <= 'Z') then + Char.chr (Char.code c + 32) + else + c) + + let uncapitalize_ascii s = + if s <> "" then + (lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1)) + else + s + + let uppercase_ascii = + replace_chars + (fun c -> + if (c >= 'a' && c <= 'z') then + Char.chr (Char.code c - 32) + else + c) + + let capitalize_ascii s = + if s <> "" then + (uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1)) + else + s end @@ -315,19 +342,15 @@ module OASISUtils = struct let compare_csl s1 s2 = - String.compare (String.lowercase s1) (String.lowercase s2) + String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2) module HashStringCsl = Hashtbl.Make (struct type t = string - - let equal s1 s2 = - (String.lowercase s1) = (String.lowercase s2) - - let hash s = - Hashtbl.hash (String.lowercase s) + let equal s1 s2 = (compare_csl s1 s2) = 0 + let hash s = Hashtbl.hash (OASISString.lowercase_ascii s) end) module SetStringCsl = @@ -365,7 +388,7 @@ module OASISUtils = struct else buf in - String.lowercase buf + OASISString.lowercase_ascii buf end @@ -471,7 +494,7 @@ module PropList = struct order = Queue.create (); name_norm = (if case_insensitive then - String.lowercase + OASISString.lowercase_ascii else fun s -> s); } @@ -1822,13 +1845,13 @@ module OASISUnixPath = struct let capitalize_file f = let dir = dirname f in let base = basename f in - concat dir (String.capitalize base) + concat dir (OASISString.capitalize_ascii base) let uncapitalize_file f = let dir = dirname f in let base = basename f in - concat dir (String.uncapitalize base) + concat dir (OASISString.uncapitalize_ascii base) end @@ -2890,7 +2913,7 @@ module OASISFileUtil = struct end -# 2893 "setup.ml" +# 2916 "setup.ml" module BaseEnvLight = struct (* # 22 "src/base/BaseEnvLight.ml" *) @@ -2995,7 +3018,7 @@ module BaseEnvLight = struct end -# 2998 "setup.ml" +# 3021 "setup.ml" module BaseContext = struct (* # 22 "src/base/BaseContext.ml" *) @@ -5406,7 +5429,7 @@ module BaseSetup = struct end -# 5409 "setup.ml" +# 5432 "setup.ml" module InternalConfigurePlugin = struct (* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *) @@ -5845,8 +5868,8 @@ module InternalInstallPlugin = struct let make_fnames modul sufx = List.fold_right begin fun sufx accu -> - (String.capitalize modul ^ sufx) :: - (String.uncapitalize modul ^ sufx) :: + (OASISString.capitalize_ascii modul ^ sufx) :: + (OASISString.uncapitalize_ascii modul ^ sufx) :: accu end sufx @@ -6270,7 +6293,7 @@ module InternalInstallPlugin = struct end -# 6273 "setup.ml" +# 6296 "setup.ml" module OCamlbuildCommon = struct (* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *) @@ -6648,7 +6671,7 @@ module OCamlbuildDocPlugin = struct end -# 6651 "setup.ml" +# 6674 "setup.ml" open OASISTypes;; let setup_t = @@ -6769,6 +6792,36 @@ let setup_t = Some "Build server with simulator support"; flag_default = [(OASISExpr.EBool true, true)] }); + Library + ({ + cs_name = "profiling"; + cs_data = PropList.Data.create (); + cs_plugin_data = [] + }, + { + bs_build = [(OASISExpr.EBool true, true)]; + bs_install = [(OASISExpr.EBool true, false)]; + bs_path = "profiling"; + bs_compiled_object = Best; + bs_build_depends = []; + bs_build_tools = [ExternalTool "ocamlbuild"]; + bs_c_sources = []; + bs_data_files = []; + bs_ccopt = [(OASISExpr.EBool true, [])]; + bs_cclib = [(OASISExpr.EBool true, [])]; + bs_dlllib = [(OASISExpr.EBool true, [])]; + bs_dllpath = [(OASISExpr.EBool true, [])]; + bs_byteopt = [(OASISExpr.EBool true, [])]; + bs_nativeopt = [(OASISExpr.EBool true, [])] + }, + { + lib_modules = ["Coverage"]; + lib_pack = false; + lib_internal_modules = []; + lib_findlib_parent = None; + lib_findlib_name = Some "profiling"; + lib_findlib_containers = [] + }); Library ({ cs_name = "xenopsd"; @@ -6782,7 +6835,6 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); FindlibPackage ("threads", None); FindlibPackage ("threads.posix", None); FindlibPackage ("uuidm", None); @@ -6863,10 +6915,10 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); FindlibPackage ("xenctrl", None); FindlibPackage ("uuidm", None); - FindlibPackage ("cmdliner", None) + FindlibPackage ("cmdliner", None); + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = []; @@ -6894,9 +6946,9 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); InternalLibrary "xenopsd"; - FindlibPackage ("cmdliner", None) + FindlibPackage ("cmdliner", None); + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = []; @@ -6931,7 +6983,6 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); FindlibPackage ("xenctrl", None); InternalLibrary "xenopsd"; FindlibPackage ("xenstore", None); @@ -6946,7 +6997,8 @@ let setup_t = FindlibPackage ("xcp.rrd", None); FindlibPackage ("rrd", None); FindlibPackage ("sexplib", None); - FindlibPackage ("xcp-inventory", None) + FindlibPackage ("xcp-inventory", None); + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = ["fsync_stubs.c"; "xenctrlext_stubs.c"]; @@ -6974,13 +7026,13 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); InternalLibrary "xenopsd"; FindlibPackage ("xenstore", None); FindlibPackage ("xenstore.unix", None); FindlibPackage ("xenstore_transport", None); FindlibPackage ("xenstore_transport.unix", None); - FindlibPackage ("threads", None) + FindlibPackage ("threads", None); + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = []; @@ -7012,8 +7064,8 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); - InternalLibrary "xenopsd" + InternalLibrary "xenopsd"; + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = []; @@ -7048,14 +7100,14 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); InternalLibrary "xenopsd"; FindlibPackage ("rpclib", None); FindlibPackage ("forkexec", None); FindlibPackage ("xcp", None); FindlibPackage ("xcp.storage", None); FindlibPackage ("sexplib", None); - FindlibPackage ("libvirt", None) + FindlibPackage ("libvirt", None); + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = []; @@ -7090,7 +7142,6 @@ let setup_t = bs_compiled_object = Best; bs_build_depends = [ - FindlibPackage ("bisect_ppx", None); FindlibPackage ("xenlight", None); FindlibPackage ("xentoollog", None); FindlibPackage ("xenctrl", None); @@ -7106,7 +7157,8 @@ let setup_t = FindlibPackage ("xcp.memory", None); FindlibPackage ("sexplib", None); FindlibPackage ("xcp-inventory", None); - FindlibPackage ("optcomp", None) + FindlibPackage ("optcomp", None); + InternalLibrary "profiling" ]; bs_build_tools = [ExternalTool "ocamlbuild"]; bs_c_sources = ["fsync_stubs.c"; "poll_stubs.c"]; @@ -7128,9 +7180,9 @@ let setup_t = plugin_data = [] }; oasis_fn = Some "_oasis"; - oasis_version = "0.4.5"; + oasis_version = "0.4.6"; oasis_digest = - Some "\169\019\155\1528\2274\199\183\007C\142\230\031\2419"; + Some "0\155\"O\170\029\131\031\024\144\024\186\191\135\132y"; oasis_exec = None; oasis_setup_args = []; setup_update = false @@ -7138,6 +7190,6 @@ let setup_t = let setup () = BaseSetup.setup setup_t;; -# 7142 "setup.ml" +# 7194 "setup.ml" (* OASIS_STOP *) let () = setup ();; diff --git a/xc/xenops_xc_main.ml b/xc/xenops_xc_main.ml index 7499674a6..a76769151 100644 --- a/xc/xenops_xc_main.ml +++ b/xc/xenops_xc_main.ml @@ -46,6 +46,7 @@ let make_var_run_xen () = (* Start the program with the xen backend *) let _ = + Coverage.init "xenopsd-xc"; (* set up coverage profiling *) Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".classic"; Xenops_utils.set_root "xenopsd/classic"; Xenopsd.configure From a0b917e48a63da825eb08d4e156f73879f6aa330 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Mon, 16 May 2016 11:08:45 +0100 Subject: [PATCH 08/13] CP-17268 remove init code from xenopsd.ml (moved to xc/xenops_xc_main.ml) This was missed in the previous commit. Signed-off-by: Christian Lindig --- lib/xenopsd.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/xenopsd.ml b/lib/xenopsd.ml index 7e9c911c8..10b77c5bc 100644 --- a/lib/xenopsd.ml +++ b/lib/xenopsd.ml @@ -149,7 +149,6 @@ let main backend = Sys.set_signal Sys.sigpipe Sys.Signal_ignore; Sys.set_signal Sys.sigterm (Sys.Signal_handle signal_handler); - Coverage.init name; (* set up coverage profiling *) Xenops_utils.set_fs_backend (Some (if !persist From d7411e1541660b5adf93a9720e652d5f2bcee2af Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Mon, 16 May 2016 12:27:32 +0100 Subject: [PATCH 09/13] CP-17268 fix some typos, update README Signed-off-by: Christian Lindig --- COVERAGE.md | 2 +- README.md | 22 ++-------------------- profiling/coverage.ml | 4 ++-- profiling/coverage.mli | 2 +- 4 files changed, 6 insertions(+), 24 deletions(-) diff --git a/COVERAGE.md b/COVERAGE.md index ed8673b1f..d8ea101f1 100644 --- a/COVERAGE.md +++ b/COVERAGE.md @@ -23,7 +23,7 @@ of it. During program execution, a binary writes coverage data to - /tmp/bisect-lunarossa-*.out + /tmp/bisect--*.out This can be overridden by setting the `BISECT_FILE` environment variable, which is otherwise set at startup using the code in diff --git a/README.md b/README.md index 355ddfc91..1a7c739f0 100644 --- a/README.md +++ b/README.md @@ -11,26 +11,8 @@ and provides a simple RPC control interface to the layer above (typically xapi). ## Coverage Profiling -This branch adds coverage profiling with bisect_ppx. Binaries write -`bisect*.out` files, when they exit to the current directory. These files -can be analysed with bisect-ppx-report: - - bisect-ppx-report -I _build -html coverage *.out - bisect-ppx-report -I _build -text coverage.txt *.out - -## Location of Profiling Data - -By default, an instrumented binary writes to `$CWD/bisect*.out`. In the -case of xenopsd in producition, this would be `/`. To avoid writing to `/` -and to avoid several services writing to the same place, start xenopsd -binaries with an evironment variable pointing to a better place: - - BISECT_FILE="/tmp/bisect-xenopsd" - -Function `Bisect_setup.init name` sets the environment variable if it is -unset from inside the program such that log data is written to the temp -directory (respecting TMP and TEMP env vars if set). However, logging to -$CWD will still work even if the `init` function is not called. +This code can be profiled for coverage. See [COVERAGE.md]. +[COVERAGE.md]: ./COVERAGE.md diff --git a/profiling/coverage.ml b/profiling/coverage.ml index adc136a55..29e68f3ca 100644 --- a/profiling/coverage.ml +++ b/profiling/coverage.ml @@ -1,6 +1,6 @@ (** This module sets up the env variable for bisect_ppx which describes - * where log files are writte + * where log files are written. *) let (//) = Filename.concat @@ -25,7 +25,7 @@ let tmpdir = Not_found -> failwith "can't find temp directory "^__LOC__ (** [init name] sets up coverage profiling for binary [name]. You could - * use [Sys.argv.(0) for name + * use [Sys.argv.(0)] for [name]. *) let init name = try diff --git a/profiling/coverage.mli b/profiling/coverage.mli index f9a84b34e..25e9f6005 100644 --- a/profiling/coverage.mli +++ b/profiling/coverage.mli @@ -1,7 +1,7 @@ (** [init name] sets up coverage profiling for binary [name]. You could - * use [Sys.argv.(0) for name + * use [Sys.argv.(0)] for [name]. *) val init: string -> unit From 56d49e313f06fd8223c51873effa763a479d074d Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Mon, 16 May 2016 17:01:28 +0100 Subject: [PATCH 10/13] CP-17268 set up more binaries for coverage analysis Signed-off-by: Christian Lindig --- libvirt/xenops_libvirt_main.ml | 1 + simulator/xenops_simulator_main.ml | 1 + xc/watch_test.ml | 4 +++- xl/xenops_xl_main.ml | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libvirt/xenops_libvirt_main.ml b/libvirt/xenops_libvirt_main.ml index 02cfc4483..393b396f0 100644 --- a/libvirt/xenops_libvirt_main.ml +++ b/libvirt/xenops_libvirt_main.ml @@ -16,6 +16,7 @@ let specific_essential_paths = Path.hvm_guests @ Path.network_configuration (* Start the program with the libvirt backend *) let _ = + Coverage.init "xenopsd-libvirt"; Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".libvirt"; Xenops_utils.set_root "xenopsd/libvirt"; Xenopsd.configure diff --git a/simulator/xenops_simulator_main.ml b/simulator/xenops_simulator_main.ml index 95ff47d9d..b465e9e92 100644 --- a/simulator/xenops_simulator_main.ml +++ b/simulator/xenops_simulator_main.ml @@ -14,6 +14,7 @@ (* Start the program with the simulator backend *) let _ = + Coverage.init "xenops-simulator"; Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".simulator"; Xenops_utils.set_root "xenopsd/simulator"; Xenopsd.configure (); diff --git a/xc/watch_test.ml b/xc/watch_test.ml index cdb21304f..c45b605d9 100644 --- a/xc/watch_test.ml +++ b/xc/watch_test.ml @@ -47,5 +47,7 @@ module Tests = struct end let _ = + Coverage.init "xenopsd-watch-test"; Scheduler.start(); - Tests.go () + Tests.go (); + exit 0 (* run at_exit hooks *) diff --git a/xl/xenops_xl_main.ml b/xl/xenops_xl_main.ml index 8b4a58cdb..ea3a91abf 100644 --- a/xl/xenops_xl_main.ml +++ b/xl/xenops_xl_main.ml @@ -50,6 +50,7 @@ let make_var_run_xen () = (* Start the program with the xenlight backend *) let _ = + Coverage.init "xenopsd-xl"; Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".xenlight"; Xenops_utils.set_root "xenopsd/xenlight"; Xenopsd.configure From e970a0bbe44e15c4cb1ca26f5ed0591a45a6b830 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Tue, 17 May 2016 10:02:43 +0100 Subject: [PATCH 11/13] CP-17268 simplify finding tmpdir, fix indentation Signed-off-by: Christian Lindig --- Makefile | 13 +++++++------ libvirt/xenops_libvirt_main.ml | 4 +++- profiling/coverage.ml | 31 +++++++----------------------- simulator/xenops_simulator_main.ml | 2 +- 4 files changed, 18 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 67f2275e5..98ea92ab9 100644 --- a/Makefile +++ b/Makefile @@ -98,11 +98,9 @@ release: mv _oasis.tmp _oasis oasis setup -# make coverage -# prepares for building with coverage analysis -# -# make uncover -# reverses the setup from "make coverage" +# make coverage - prepares for building with coverage analysis +# make uncover - reverses the setup from "make coverage" +# make report - create coverage/index.html coverage: _tags _tags.coverage test ! -f _tags.orig && mv _tags _tags.orig || true @@ -111,5 +109,8 @@ coverage: _tags _tags.coverage uncover: _tags.orig mv _tags.orig _tags -.PHONY: default coverage uncover +report: + bisect-ppx-report -I _build -html coverage /tmp/bisect-xenops*out + +.PHONY: report coverage uncover diff --git a/libvirt/xenops_libvirt_main.ml b/libvirt/xenops_libvirt_main.ml index 393b396f0..402544954 100644 --- a/libvirt/xenops_libvirt_main.ml +++ b/libvirt/xenops_libvirt_main.ml @@ -16,7 +16,7 @@ let specific_essential_paths = Path.hvm_guests @ Path.network_configuration (* Start the program with the libvirt backend *) let _ = - Coverage.init "xenopsd-libvirt"; + Coverage.init "xenopsd-libvirt"; Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".libvirt"; Xenops_utils.set_root "xenopsd/libvirt"; Xenopsd.configure @@ -24,3 +24,5 @@ let _ = (); Xenopsd.main (module Xenops_server_libvirt: Xenops_server_plugin.S) + +(* vim: ts=2 sw=2 noet *) diff --git a/profiling/coverage.ml b/profiling/coverage.ml index 29e68f3ca..1dbdff6a6 100644 --- a/profiling/coverage.ml +++ b/profiling/coverage.ml @@ -3,33 +3,16 @@ * where log files are written. *) -let (//) = Filename.concat - -let is_dir = function - | "" -> false - | path -> try Sys.is_directory path with Sys_error _ -> false - -(* [tmpdir] points to a directory for temporary files *) -let tmpdir = - let getenv n = try Sys.getenv n with Not_found -> "" in - let dirs = - [ getenv "TMP" - ; getenv "TEMP" - ; "/tmp" - ; "/usr/tmp" - ; "/var/tmp" - ] in - try - List.find is_dir dirs - with - Not_found -> failwith "can't find temp directory "^__LOC__ (** [init name] sets up coverage profiling for binary [name]. You could * use [Sys.argv.(0)] for [name]. *) + let init name = - try - ignore (Sys.getenv "BISECT_FILE") - with Not_found -> - Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s-" name) + let (//) = Filename.concat in + let tmpdir = Filename.get_temp_dir_name () in + try + ignore (Sys.getenv "BISECT_FILE") + with Not_found -> + Unix.putenv "BISECT_FILE" (tmpdir // Printf.sprintf "bisect-%s-" name) diff --git a/simulator/xenops_simulator_main.ml b/simulator/xenops_simulator_main.ml index b465e9e92..cd3c30a8e 100644 --- a/simulator/xenops_simulator_main.ml +++ b/simulator/xenops_simulator_main.ml @@ -14,7 +14,7 @@ (* Start the program with the simulator backend *) let _ = - Coverage.init "xenops-simulator"; + Coverage.init "xenops-simulator"; Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".simulator"; Xenops_utils.set_root "xenopsd/simulator"; Xenopsd.configure (); From 49f10245ffacdbfb442a3d35d3ef05a251f702f3 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Tue, 17 May 2016 10:52:13 +0100 Subject: [PATCH 12/13] CP-17268 don't profile for coverage by default This was an oversight in the last commit. Signed-off-by: Christian Lindig --- _tags | 6 ------ 1 file changed, 6 deletions(-) diff --git a/_tags b/_tags index 597f6854b..22df0dad6 100644 --- a/_tags +++ b/_tags @@ -1,9 +1,3 @@ -# START_COVERAGE -# coverage analysis with bisect_ppx -# compile and link with package bisect_ppx -<**/*.ml{,i,y}>: pkg_bisect_ppx -<**/*.native>: pkg_bisect_ppx -# END_COVERAGE # OASIS_START # DO NOT EDIT (digest: 75c8d08bbb53d180415f0183181b9cf1) # Ignore VCS directories, you can use the same kind of rule outside From 5d87a67cba6b4cbf3ae6d238dd0288e8b4aeb943 Mon Sep 17 00:00:00 2001 From: Christian Lindig Date: Thu, 19 May 2016 16:06:46 +0100 Subject: [PATCH 13/13] CP-17268 Fix more indentation Signed-off-by: Christian Lindig --- xc/xenops_xc_main.ml | 2 +- xl/xenops_xl_main.ml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xc/xenops_xc_main.ml b/xc/xenops_xc_main.ml index a76769151..19d4c0a23 100644 --- a/xc/xenops_xc_main.ml +++ b/xc/xenops_xc_main.ml @@ -46,7 +46,7 @@ let make_var_run_xen () = (* Start the program with the xen backend *) let _ = - Coverage.init "xenopsd-xc"; (* set up coverage profiling *) + Coverage.init "xenopsd-xc"; (* set up coverage profiling *) Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".classic"; Xenops_utils.set_root "xenopsd/classic"; Xenopsd.configure diff --git a/xl/xenops_xl_main.ml b/xl/xenops_xl_main.ml index ea3a91abf..91972ea45 100644 --- a/xl/xenops_xl_main.ml +++ b/xl/xenops_xl_main.ml @@ -50,7 +50,7 @@ let make_var_run_xen () = (* Start the program with the xenlight backend *) let _ = - Coverage.init "xenopsd-xl"; + Coverage.init "xenopsd-xl"; Xenops_interface.queue_name := !Xenops_interface.queue_name ^ ".xenlight"; Xenops_utils.set_root "xenopsd/xenlight"; Xenopsd.configure