@@ -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. *)
66external 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+
814let 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