Skip to content

Commit d03e0d6

Browse files
committed
Merge pull request #11 from djs55/experimental-backtraces
Transport backtraces through the API
2 parents e31eea9 + 8cbc205 commit d03e0d6

File tree

6 files changed

+232
-124
lines changed

6 files changed

+232
-124
lines changed

_oasis

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ Executable xapi_script_storage
1313
MainIs: main.ml
1414
Custom: true
1515
Install: false
16-
BuildDepends: xcp, xcp.storage, async_inotify, threads, message_switch.async, rpclib, xapi-storage
16+
BuildDepends: xcp, xcp.storage, async_inotify, threads, message_switch.async, rpclib, xapi-storage, sexplib, sexplib.syntax, rpclib, rpclib.syntax

_tags

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# OASIS_START
2-
# DO NOT EDIT (digest: 7c0996ac9ce2363431af4daae4cbaead)
2+
# DO NOT EDIT (digest: d4caced815577ed0a5b4b8487e4f2276)
33
# Ignore VCS directories, you can use the same kind of rule outside
44
# OASIS_START/STOP if you want to exclude directories that contains
55
# useless stuff for the build process
6+
true: annot, bin_annot
67
<**/.svn>: -traverse
78
<**/.svn>: not_hygienic
89
".bzr": -traverse
@@ -17,16 +18,22 @@
1718
<main.{native,byte}>: pkg_async_inotify
1819
<main.{native,byte}>: pkg_message_switch.async
1920
<main.{native,byte}>: pkg_rpclib
21+
<main.{native,byte}>: pkg_rpclib.syntax
22+
<main.{native,byte}>: pkg_sexplib
23+
<main.{native,byte}>: pkg_sexplib.syntax
2024
<main.{native,byte}>: pkg_threads
2125
<main.{native,byte}>: pkg_xapi-storage
2226
<main.{native,byte}>: pkg_xcp
2327
<main.{native,byte}>: pkg_xcp.storage
24-
<*.ml{,i}>: pkg_async_inotify
25-
<*.ml{,i}>: pkg_message_switch.async
26-
<*.ml{,i}>: pkg_rpclib
27-
<*.ml{,i}>: pkg_threads
28-
<*.ml{,i}>: pkg_xapi-storage
29-
<*.ml{,i}>: pkg_xcp
30-
<*.ml{,i}>: pkg_xcp.storage
28+
<*.ml{,i,y}>: pkg_async_inotify
29+
<*.ml{,i,y}>: pkg_message_switch.async
30+
<*.ml{,i,y}>: pkg_rpclib
31+
<*.ml{,i,y}>: pkg_rpclib.syntax
32+
<*.ml{,i,y}>: pkg_sexplib
33+
<*.ml{,i,y}>: pkg_sexplib.syntax
34+
<*.ml{,i,y}>: pkg_threads
35+
<*.ml{,i,y}>: pkg_xapi-storage
36+
<*.ml{,i,y}>: pkg_xcp
37+
<*.ml{,i,y}>: pkg_xcp.storage
3138
<main.{native,byte}>: custom
3239
# OASIS_STOP

main.ml

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@
1313
*)
1414
module U = Unix
1515
module R = Rpc
16+
module B = Backtrace
1617

1718
open Core.Std
1819
open Async.Std
1920

21+
open Types
22+
2023
let use_syslog = ref false
2124

2225
let info fmt =
2326
Printf.ksprintf (fun s ->
2427
if !use_syslog then begin
2528
(* FIXME: this is synchronous and will block other I/O *)
26-
Core.Syslog.syslog ~level:Core.Syslog.Level.INFO ~add_stderr:true s;
29+
Core.Syslog.syslog ~level:Core.Syslog.Level.INFO s;
2730
return ()
2831
end else begin
2932
let w = Lazy.force Writer.stderr in
@@ -38,6 +41,20 @@ let backend_error name args =
3841
let exnty = Exception.Backend_error (name, args) in
3942
Exception.rpc_of_exnty exnty
4043

44+
let backend_backtrace_error name args error =
45+
match List.zip error.files error.lines with
46+
| None -> backend_error "SCRIPT_FAILED" [ "malformed backtrace in error output" ]
47+
| Some pairs ->
48+
let backtrace =
49+
pairs
50+
|> List.map ~f:(fun (filename, line) -> { B.Interop.filename; line })
51+
|> B.Interop.to_backtrace
52+
|> B.sexp_of_t
53+
|> Sexplib.Sexp.to_string in
54+
let open Storage_interface in
55+
let exnty = Exception.Backend_error_with_backtrace(name, backtrace :: args) in
56+
Exception.rpc_of_exnty exnty
57+
4158
let missing_uri () =
4259
backend_error "MISSING_URI" [ "Please include a URI in the device-config" ]
4360

@@ -70,7 +87,16 @@ let fork_exec_rpc root_dir script_name args response_of_rpc =
7087
>>= fun output ->
7188
begin match output.Process.Output.exit_status with
7289
| Error (`Exit_non_zero code) ->
73-
return (Error (backend_error "SCRIPT_FAILED" [ script_name; "non-zero exit"; string_of_int code; output.Process.Output.stdout; output.Process.Output.stderr ]))
90+
(* Expect an exception and backtrace on stderr *)
91+
begin match Or_error.try_with (fun () -> Jsonrpc.of_string output.Process.Output.stderr) with
92+
| Error _ ->
93+
return (Error (backend_error "SCRIPT_FAILED" [ script_name; "non-zero exit and bad json on stderr"; string_of_int code; output.Process.Output.stdout; output.Process.Output.stderr ]))
94+
| Ok response ->
95+
begin match Or_error.try_with (fun () -> error_of_rpc response) with
96+
| Error _ -> return (Error (backend_error "SCRIPT_FAILED" [ script_name; "non-zero exit and bad json on stderr"; string_of_int code; output.Process.Output.stdout; output.Process.Output.stderr ]))
97+
| Ok x -> return (Error(backend_backtrace_error "SCRIPT_FAILED" [ script_name; "non-zero exit"; string_of_int code; output.Process.Output.stdout ] x))
98+
end
99+
end
74100
| Error (`Signal signal) ->
75101
return (Error (backend_error "SCRIPT_FAILED" [ script_name; "signalled"; Signal.to_string signal; output.Process.Output.stdout; output.Process.Output.stderr ]))
76102
| Ok () ->

myocamlbuild.ml

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(* OASIS_START *)
2-
(* DO NOT EDIT (digest: 5a9a2168dcb86db37476d58b8c0e25b3) *)
2+
(* DO NOT EDIT (digest: 2b686a81cec9fb16d1640bda36a68fbd) *)
33
module OASISGettext = struct
44
(* # 22 "src/oasis/OASISGettext.ml" *)
55

@@ -249,6 +249,9 @@ module MyOCamlbuildFindlib = struct
249249
*)
250250
open Ocamlbuild_plugin
251251

252+
type conf =
253+
{ no_automatic_syntax: bool;
254+
}
252255

253256
(* these functions are not really officially exported *)
254257
let run_and_read =
@@ -315,7 +318,7 @@ module MyOCamlbuildFindlib = struct
315318

316319
(* This lists all supported packages. *)
317320
let find_packages () =
318-
List.map before_space (split_nl & run_and_read "ocamlfind list")
321+
List.map before_space (split_nl & run_and_read (exec_from_conf "ocamlfind" ^ " list"))
319322

320323

321324
(* Mock to list available syntaxes. *)
@@ -338,7 +341,7 @@ module MyOCamlbuildFindlib = struct
338341
]
339342

340343

341-
let dispatch =
344+
let dispatch conf =
342345
function
343346
| After_options ->
344347
(* By using Before_options one let command line options have an higher
@@ -357,31 +360,39 @@ module MyOCamlbuildFindlib = struct
357360
* -linkpkg *)
358361
flag ["ocaml"; "link"; "program"] & A"-linkpkg";
359362

360-
(* For each ocamlfind package one inject the -package option when
361-
* compiling, computing dependencies, generating documentation and
362-
* linking. *)
363-
List.iter
364-
begin fun pkg ->
365-
let base_args = [A"-package"; A pkg] in
366-
(* TODO: consider how to really choose camlp4o or camlp4r. *)
367-
let syn_args = [A"-syntax"; A "camlp4o"] in
368-
let args =
369-
(* Heuristic to identify syntax extensions: whether they end in
370-
".syntax"; some might not.
371-
*)
372-
if Filename.check_suffix pkg "syntax" ||
373-
List.mem pkg well_known_syntax then
374-
syn_args @ base_args
375-
else
376-
base_args
377-
in
378-
flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
379-
flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
380-
flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
381-
flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
382-
flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
383-
end
384-
(find_packages ());
363+
if not (conf.no_automatic_syntax) then begin
364+
(* For each ocamlfind package one inject the -package option when
365+
* compiling, computing dependencies, generating documentation and
366+
* linking. *)
367+
List.iter
368+
begin fun pkg ->
369+
let base_args = [A"-package"; A pkg] in
370+
(* TODO: consider how to really choose camlp4o or camlp4r. *)
371+
let syn_args = [A"-syntax"; A "camlp4o"] in
372+
let (args, pargs) =
373+
(* Heuristic to identify syntax extensions: whether they end in
374+
".syntax"; some might not.
375+
*)
376+
if Filename.check_suffix pkg "syntax" ||
377+
List.mem pkg well_known_syntax then
378+
(syn_args @ base_args, syn_args)
379+
else
380+
(base_args, [])
381+
in
382+
flag ["ocaml"; "compile"; "pkg_"^pkg] & S args;
383+
flag ["ocaml"; "ocamldep"; "pkg_"^pkg] & S args;
384+
flag ["ocaml"; "doc"; "pkg_"^pkg] & S args;
385+
flag ["ocaml"; "link"; "pkg_"^pkg] & S base_args;
386+
flag ["ocaml"; "infer_interface"; "pkg_"^pkg] & S args;
387+
388+
(* TODO: Check if this is allowed for OCaml < 3.12.1 *)
389+
flag ["ocaml"; "compile"; "package("^pkg^")"] & S pargs;
390+
flag ["ocaml"; "ocamldep"; "package("^pkg^")"] & S pargs;
391+
flag ["ocaml"; "doc"; "package("^pkg^")"] & S pargs;
392+
flag ["ocaml"; "infer_interface"; "package("^pkg^")"] & S pargs;
393+
end
394+
(find_packages ());
395+
end;
385396

386397
(* Like -package but for extensions syntax. Morover -syntax is useless
387398
* when linking. *)
@@ -546,12 +557,13 @@ module MyOCamlbuildBase = struct
546557

547558
(* When ocaml link something that use the C library, then one
548559
need that file to be up to date.
560+
This holds both for programs and for libraries.
549561
*)
550-
dep ["link"; "ocaml"; "program"; tag_libstubs lib]
551-
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
562+
dep ["link"; "ocaml"; tag_libstubs lib]
563+
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
552564

553-
dep ["compile"; "ocaml"; "program"; tag_libstubs lib]
554-
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
565+
dep ["compile"; "ocaml"; tag_libstubs lib]
566+
[dir/"lib"^(nm_libstubs lib)^"."^(!Options.ext_lib)];
555567

556568
(* TODO: be more specific about what depends on headers *)
557569
(* Depends on .h files *)
@@ -580,25 +592,27 @@ module MyOCamlbuildBase = struct
580592
()
581593

582594

583-
let dispatch_default t =
595+
let dispatch_default conf t =
584596
dispatch_combine
585597
[
586598
dispatch t;
587-
MyOCamlbuildFindlib.dispatch;
599+
MyOCamlbuildFindlib.dispatch conf;
588600
]
589601

590602

591603
end
592604

593605

594-
# 594 "myocamlbuild.ml"
606+
# 606 "myocamlbuild.ml"
595607
open Ocamlbuild_plugin;;
596608
let package_default =
597609
{MyOCamlbuildBase.lib_ocaml = []; lib_c = []; flags = []; includes = []}
598610
;;
599611

600-
let dispatch_default = MyOCamlbuildBase.dispatch_default package_default;;
612+
let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
613+
614+
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
601615

602-
# 603 "myocamlbuild.ml"
616+
# 617 "myocamlbuild.ml"
603617
(* OASIS_STOP *)
604618
Ocamlbuild_plugin.dispatch dispatch_default;;

0 commit comments

Comments
 (0)