Skip to content

Commit 90b5d71

Browse files
committed
fixup! Windows safe kill.
1 parent fb212b9 commit 90b5d71

1 file changed

Lines changed: 27 additions & 5 deletions

File tree

lib/olly_common/launch.ml

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ external is_process_alive : int -> bool = "olly_is_process_alive"
55
On Unix it's the identity function since the handle IS the PID. *)
66
external get_process_id : int -> int = "olly_get_process_id"
77

8+
(* Windows has no SIGKILL — Unix.kill only routes SIGTERM through
9+
TerminateProcess. On Unix we want SIGKILL because some test programs
10+
(e.g. tight integer loops) never reach a signal-poll point and so
11+
ignore SIGTERM. *)
12+
let terminate_signal = if Sys.win32 then Sys.sigterm else Sys.sigkill
13+
814
let lost_events ring_id num =
915
Printf.eprintf "[ring_id=%d] Lost %d events\n%!" ring_id num
1016

@@ -89,11 +95,26 @@ let exec_process (config : runtime_events_config) (args : string list) :
8995
let child_pid = get_process_id child_handle in
9096
(* On Windows Unix.kill takes a PID (uses OpenProcess) but Unix.waitpid
9197
takes the HANDLE returned by create_process — they are different
92-
values. On Unix the handle and PID coincide. *)
98+
values. On Unix the handle and PID coincide.
99+
100+
We poll waitpid with WNOHANG rather than blocking indefinitely: if
101+
the kill didn't take for any reason, hanging the test suite for
102+
hours is worse than reporting and moving on. *)
93103
let kill () =
94-
(try Unix.kill child_pid Sys.sigkill
104+
(try Unix.kill child_pid terminate_signal
95105
with Unix.Unix_error _ | Invalid_argument _ -> ());
96-
try ignore (Unix.waitpid [] child_handle) with Unix.Unix_error _ -> ()
106+
let deadline = Unix.gettimeofday () +. 5.0 in
107+
let rec wait () =
108+
if Unix.gettimeofday () >= deadline then ()
109+
else
110+
match Unix.waitpid [ Unix.WNOHANG ] child_handle with
111+
| 0, _ ->
112+
Unix.sleepf 0.02;
113+
wait ()
114+
| _, _ -> ()
115+
| exception Unix.Unix_error _ -> ()
116+
in
117+
wait ()
97118
in
98119
(* Poll until we can create a cursor for the child's ring buffer.
99120
The OCaml runtime creates the .events file then initializes it,
@@ -172,9 +193,10 @@ let attach_process (dir : string) (pid : int) : subprocess =
172193
let alive () = is_process_alive pid
173194
and close () = Runtime_events.free_cursor cursor in
174195
(* Best-effort: we did not create the process, so we have no handle to
175-
waitpid on. Send SIGKILL and poll is_process_alive briefly. *)
196+
waitpid on. Send the platform terminate signal and poll
197+
is_process_alive briefly. *)
176198
let kill () =
177-
(try Unix.kill pid Sys.sigkill
199+
(try Unix.kill pid terminate_signal
178200
with Unix.Unix_error _ | Invalid_argument _ -> ());
179201
let deadline = Unix.gettimeofday () +. 2.0 in
180202
while is_process_alive pid && Unix.gettimeofday () < deadline do

0 commit comments

Comments
 (0)