From 4dedd34d7e7c57f226a86b20365ff3008e479fe6 Mon Sep 17 00:00:00 2001 From: Pierre Wilke <pierre.wilke@centralesupelec.fr> Date: Thu, 11 Mar 2021 11:32:00 +0100 Subject: [PATCH] =?UTF-8?q?Les=20ex=C3=A9cutions=20=C3=A9chouent=20si=20el?= =?UTF-8?q?les=20durent=20plus=20d'une=20seconde.=20Timeout=20param=C3=A9t?= =?UTF-8?q?rable=20dans=20options.ml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/options.ml | 1 + src/report.ml | 51 ++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/options.ml b/src/options.ml index 5b3df95..d3966f5 100644 --- a/src/options.ml +++ b/src/options.ml @@ -39,3 +39,4 @@ let naive_regalloc = ref true let rig_dump : string option ref = ref None let handwritten_lexer = ref Config.lex_hand let alpaga_parser = ref Config.alpaga_parser +let timeout = ref 1.0 diff --git a/src/report.ml b/src/report.ml index 94d927d..ba312d9 100644 --- a/src/report.ml +++ b/src/report.ml @@ -77,19 +77,54 @@ let record_compile_result ?error:(error=None) ?data:(data=[]) step = results := !results @ [CompRes { step; error; data}] +let kill pid sign = + try Unix.kill pid sign with + | Unix.Unix_error (e,f,p) -> + begin match e with + | ESRCH -> () + | _ -> Printf.printf "%s\n" ((Unix.error_message e)^"|"^f^"|"^p) + end + | e -> raise e + +let run_exn_to_error f x = + try f x with + | e -> Error (Printexc.to_string e) + +let timeout (f: 'a -> 'b res) (arg: 'a) (time: float) : ('b * string) res = + let pipe_r,pipe_w = Unix.pipe () in + (match Unix.fork () with + | 0 -> + let r = + run_exn_to_error f arg >>= fun v -> + OK (v, Format.flush_str_formatter ()) in + let oc = Unix.out_channel_of_descr pipe_w in + Marshal.to_channel oc r []; + close_out oc; + exit 0 + | pid0 -> + (match Unix.fork () with + | 0 -> Unix.sleepf time; + kill pid0 Sys.sigkill; + let oc = Unix.out_channel_of_descr pipe_w in + Marshal.to_channel oc (Error (Printf.sprintf "Timeout after %f seconds." time)) []; + close_out oc; + exit 0 + | pid1 -> let ic = Unix.in_channel_of_descr pipe_r in + let result = Marshal.from_channel ic in + result )) + let run step flag eval p = if flag then begin let starttime = Unix.gettimeofday () in - let res = match eval Format.str_formatter p !heapsize !params with - | exception e -> - Error (Printexc.to_string e) - | e -> e in + let res = timeout + (fun (p, params) -> eval Format.str_formatter p !heapsize params) + (p, !params) + !Options.timeout in let timerun = Unix.gettimeofday () -. starttime in - let output = Format.flush_str_formatter () in - let rres = { step ; retval = None; output; error = None; time = timerun} in + let rres = { step ; retval = None; output=""; error = None; time = timerun} in let rres = begin match res with - | OK v -> { rres with retval = v } + | OK (v, output) -> { rres with retval = v; output } | Error msg -> { rres with error = Some msg } end in results := !results @ [RunRes rres]; @@ -99,7 +134,7 @@ let run step flag eval p = Printf.sprintf "With parameters : [%s]<br>\n" (String.concat"," (List.map string_of_int !params)) ^ Printf.sprintf "Mem size : %d bytes<br>\n" !heapsize ^ Printf.sprintf "Return value : %s<br>\n" (match rres.retval with | Some v -> string_of_int v | _ -> "none") - ^ Printf.sprintf "Output : <pre style=\"padding: 1em; background-color: #ccc;\">%s</pre>\n" output + ^ Printf.sprintf "Output : <pre style=\"padding: 1em; background-color: #ccc;\">%s</pre>\n" rres.output ^ (match rres.error with | Some msg -> Printf.sprintf "Error : <pre style=\"padding: 1em; background-color: #fcc;\">\n%s</pre>\n" msg -- GitLab