diff --git a/test/test_acceptance.ml b/test/test_acceptance.ml index 58a8cf4e..283af120 100644 --- a/test/test_acceptance.ml +++ b/test/test_acceptance.ml @@ -186,8 +186,8 @@ module Pool = struct name (match status with | Unix.WEXITED n -> Printf.sprintf "with code %d" n - | Unix.WSIGNALED n -> Printf.sprintf "on signal %d" n - | Unix.WSTOPPED n -> Printf.sprintf "stopped on signal %d" n)) + | Unix.WSIGNALED n -> "on " ^ Test_support.signal_name n + | Unix.WSTOPPED n -> "stopped on " ^ Test_support.signal_name n)) | None, _ -> Some (Printf.sprintf @@ -195,8 +195,8 @@ module Pool = struct name (match status with | Unix.WEXITED n -> Printf.sprintf "exit %d" n - | Unix.WSIGNALED n -> Printf.sprintf "signal %d" n - | Unix.WSTOPPED n -> Printf.sprintf "stopped, signal %d" n)) + | Unix.WSIGNALED n -> Test_support.signal_name n + | Unix.WSTOPPED n -> "stopped on " ^ Test_support.signal_name n)) in ignore (Queue.pop inflight); match msg with diff --git a/test/test_agent.ml b/test/test_agent.ml index 62a24bef..4d04b60a 100644 --- a/test/test_agent.ml +++ b/test/test_agent.ml @@ -149,8 +149,8 @@ let () = fail "agent reload\n got: %S (%s)\n wanted: %S" text (match status with | Unix.WEXITED c -> Printf.sprintf "exit %d" c - | Unix.WSIGNALED c -> Printf.sprintf "signal %d" c - | Unix.WSTOPPED c -> Printf.sprintf "stopped %d" c) + | Unix.WSIGNALED c -> Test_support.signal_name c + | Unix.WSTOPPED c -> "stopped on " ^ Test_support.signal_name c) "1\n1000\n1007\n" end; @@ -309,8 +309,8 @@ let () = %S (exit 1)" text (match !bstat with | Unix.WEXITED c -> Printf.sprintf "exit %d" c - | Unix.WSIGNALED c -> Printf.sprintf "signal %d" c - | Unix.WSTOPPED c -> Printf.sprintf "stopped %d" c) + | Unix.WSIGNALED c -> Test_support.signal_name c + | Unix.WSTOPPED c -> "stopped on " ^ Test_support.signal_name c) "cannot listen\n" end; @@ -766,8 +766,8 @@ let () = fail "abort left status %s, wanted exit 134" (match !lstatus with | Unix.WEXITED c -> Printf.sprintf "exit %d" c - | Unix.WSIGNALED c -> Printf.sprintf "signal %d" c - | Unix.WSTOPPED c -> Printf.sprintf "stopped %d" c) + | Unix.WSIGNALED c -> Test_support.signal_name c + | Unix.WSTOPPED c -> "stopped on " ^ Test_support.signal_name c) (* The other way out, and the one that skips atexit on purpose: [abort] leaves by [_exit] so that it cannot hang on the loader lock, and the socket is therefore unlinked by hand there. A file left here would diff --git a/test/test_dev.ml b/test/test_dev.ml index 7ee6b241..83387be3 100644 --- a/test/test_dev.ml +++ b/test/test_dev.ml @@ -196,6 +196,23 @@ let () = if not (contains_sub other "flan.abi.x86") then fail "a parked program's other refusals were rewritten too: %S" other +(* A daemon's death is reported by the signal's name. [WSIGNALED] carries + OCaml's own numbering, in which SIGTERM is -11, and a SIGTERM printed as + "signal -11" was once recorded as a segfault. A real process, really + terminated, so the number is whatever [waitpid] hands back. *) +let () = + let p = + Unix.create_process "sleep" [| "sleep"; "30" |] Unix.stdin Unix.stdout + Unix.stderr + in + Unix.kill p Sys.sigterm; + match Unix.waitpid [] p with + | _, Unix.WSIGNALED n when Test_support.signal_name n = "SIGTERM" -> () + | _, Unix.WSIGNALED n -> + fail "a process ended by SIGTERM is reported as %s" + (Test_support.signal_name n) + | _, _ -> fail "a process sent SIGTERM did not end on a signal" + let () = match Sys.command "command -v clang > /dev/null 2>&1 && command -v llc > /dev/null 2>&1" with | 0 -> @@ -5143,8 +5160,8 @@ let () = (match st with | Unix.WEXITED n -> Printf.sprintf "exit %d" n | Unix.WSIGNALED n when n = Sys.sigpipe -> "killed by SIGPIPE" - | Unix.WSIGNALED n -> Printf.sprintf "signal %d" n - | Unix.WSTOPPED n -> Printf.sprintf "stopped on %d" n); + | Unix.WSIGNALED n -> Test_support.signal_name n + | Unix.WSTOPPED n -> "stopped on " ^ Test_support.signal_name n); None | exception Unix.Unix_error _ -> Some (connect rsock) in diff --git a/test/test_emacs.ml b/test/test_emacs.ml index ecee324d..c2b2ebe1 100644 --- a/test/test_emacs.ml +++ b/test/test_emacs.ml @@ -112,9 +112,10 @@ let () = match !status with | Some (Unix.WEXITED n) -> Printf.sprintf "exited with status %d" n | Some (Unix.WSIGNALED n) -> - Printf.sprintf "was killed by signal %d — nothing ran its cleanup, so \ - the socket file is stale rather than gone" n - | Some (Unix.WSTOPPED n) -> Printf.sprintf "stopped on signal %d" n + Printf.sprintf "was killed by %s — nothing ran its cleanup, so \ + the socket file is stale rather than gone" + (Test_support.signal_name n) + | Some (Unix.WSTOPPED n) -> Printf.sprintf "stopped on %s" (Test_support.signal_name n) | None -> "was still running when the client finished, and was terminated" in (* Read before the removal below, because on a failure this is the evidence diff --git a/test/test_repl.ml b/test/test_repl.ml index 9579130f..752b0679 100644 --- a/test/test_repl.ml +++ b/test/test_repl.ml @@ -326,9 +326,11 @@ let () = "the daemon had already been killed by SIGPIPE — a reply written \ into a socket whose reader had gone" | Some (Unix.WSIGNALED n) -> - Printf.printf "the daemon had already been killed by signal %d\n" n + Printf.printf "the daemon had already been killed by %s\n" + (Test_support.signal_name n) | Some (Unix.WSTOPPED n) -> - Printf.printf "the daemon was stopped on signal %d\n" n + Printf.printf "the daemon was stopped on %s\n" + (Test_support.signal_name n) | None -> print_endline "the daemon was still running at the end"); Printf.printf "\n-- the program's own output, last 4k --\n%s\n" prog_out; exit 1 diff --git a/test/test_support.ml b/test/test_support.ml index 41228ca6..a64b73a7 100644 --- a/test/test_support.ml +++ b/test/test_support.ml @@ -152,6 +152,24 @@ let rec connect ?(ms = 5000) path = thing after a failed wait is always the report of it. *) let listen_why = ref "" +(* A signal as [WSIGNALED] carries it, by name. OCaml numbers the signals it + knows negatively and in its own order — [Sys.sigterm] is -11 and + [Sys.sigsegv] is -10 — so printing the number reads as the wrong signal to + anyone who knows the POSIX table: a daemon terminated by SIGTERM was once + recorded here as "a transient signal 11", a segfault that never happened. *) +let signal_name n = + let known = + [ Sys.sigabrt, "SIGABRT"; Sys.sigalrm, "SIGALRM"; Sys.sigfpe, "SIGFPE"; + Sys.sighup, "SIGHUP"; Sys.sigill, "SIGILL"; Sys.sigint, "SIGINT"; + Sys.sigkill, "SIGKILL"; Sys.sigpipe, "SIGPIPE"; Sys.sigquit, "SIGQUIT"; + Sys.sigsegv, "SIGSEGV"; Sys.sigterm, "SIGTERM"; Sys.sigusr1, "SIGUSR1"; + Sys.sigusr2, "SIGUSR2"; Sys.sigchld, "SIGCHLD"; Sys.sigbus, "SIGBUS"; + Sys.sigtrap, "SIGTRAP"; Sys.sigxcpu, "SIGXCPU" ] + in + match List.assoc_opt n known with + | Some s -> s + | None -> Printf.sprintf "signal %d" n + let listening ?(ms = 30000) ~pid path = let died = ref None in ignore @@ -171,10 +189,10 @@ let listening ?(ms = 30000) ~pid path = | Some (Unix.WEXITED n) -> Printf.sprintf "exited with status %d before binding %s" n path | Some (Unix.WSIGNALED n) -> - Printf.sprintf "was killed by signal %d before binding %s" n path + Printf.sprintf "was killed by %s before binding %s" (signal_name n) path (* Unreachable without WUNTRACED, and here only for exhaustiveness. *) | Some (Unix.WSTOPPED n) -> - Printf.sprintf "stopped on signal %d without binding %s" n path + Printf.sprintf "stopped on %s without binding %s" (signal_name n) path | None -> Printf.sprintf "was still running after %ds without binding %s, so it was the \