Skip to content

Commit fdac157

Browse files
author
David Scott
committed
Add support for transporting backtraces
The xapi-storage/python/xapi.py library pickles up the python backtrace using json, this code parses it and converts it to the s-expression used internally by xapi. Signed-off-by: David Scott <dave.scott@eu.citrix.com>
1 parent e31eea9 commit fdac157

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
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

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 () ->

types.ml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(*
2+
* Copyright (C) Citrix Systems Inc.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published
6+
* by the Free Software Foundation; version 2.1 only. with the special
7+
* exception on linking described in file LICENSE.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*)
14+
open Sexplib.Std
15+
16+
(* This matches xapi.py:exception *)
17+
type error = {
18+
error: string;
19+
(* Python json.dumps and rpclib are not very friendly *)
20+
files: string list;
21+
lines: int list;
22+
} with rpc

0 commit comments

Comments
 (0)