diff --git a/src/trace.ml b/src/trace.ml index a617c6972..a89ab8857 100644 --- a/src/trace.ml +++ b/src/trace.ml @@ -356,7 +356,18 @@ module Make_commands (Backend : Backend_intf.S) = struct | Core_unix.Unix_error (_, (_ : string), (_ : string)) -> (* We raced, but it's OK because the child still exited. *) ()); - let%bind.Deferred (_ : Core_unix.Exit_or_signal.t) = Async_unix.Unix.waitpid pid in + (* [Monitor.try_with] because [waitpid] raises if perf died before we got here. *) + let%bind.Deferred (waitpid_result : (Core_unix.Exit_or_signal.t, exn) result) = + Monitor.try_with (fun () -> Async_unix.Unix.waitpid pid) + in + (match waitpid_result with + | Ok _ -> () + | Error error -> + Core.eprintf + !"Warning: [perf] exited suspiciously quickly; it may have crashed.\n\ + Error: %{Exn}\n\ + %!" + error); (* This is still a little racey, but it's the best we can do without pidfds. *) Ivar.fill exited_ivar (); let%bind () = detach attachment in