Skip to content

Commit

Permalink
Restore default SIGINT behavior after taking snapshot
Browse files Browse the repository at this point in the history
This feels like a hack, but it works for now pending discussion with
async devs.

Signed-off-by: Tudor Brindus <[email protected]>
  • Loading branch information
Xyene committed Feb 19, 2024
1 parent efe513c commit 492afe4
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions src/trace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -454,16 +454,14 @@ module Make_commands (Backend : Backend_intf.S) = struct
Ptrace.resume pid;
(* Forward ^C to the child, unless it has already exited. *)
let exited_ivar = Ivar.create () in
Async_unix.Signal.handle
~stop:(Ivar.read exited_ivar)
Async_unix.Signal.terminating
~f:(fun signal ->
try
UnixLabels.kill ~pid:(Pid.to_int pid) ~signal:(Signal_unix.to_system_int signal)
with
| Core_unix.Unix_error (_, (_ : string), (_ : string)) ->
(* We raced, but it's OK because the child still exited. *)
());
let stop = Ivar.read exited_ivar in
Async_unix.Signal.handle ~stop Async_unix.Signal.terminating ~f:(fun signal ->
try
UnixLabels.kill ~pid:(Pid.to_int pid) ~signal:(Signal_unix.to_system_int signal)
with
| Core_unix.Unix_error (_, (_ : string), (_ : string)) ->
(* We raced, but it's OK because the child still exited. *)
());
(* [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)
Expand All @@ -478,6 +476,12 @@ module Make_commands (Backend : Backend_intf.S) = struct
error);
(* This is still a little racey, but it's the best we can do without pidfds. *)
Ivar.fill exited_ivar ();
(* CR-someday tbrindus: [~stop] doesn't make [Async_unix.Signal.handle] restore signal
handlers to their default state, so the decoding step won't be ^C-able. Restore
SIGINT's handler here. Ideally we'd restore all [terminating] handlers to their
default behavior, but I'm not convinced that doesn't break Async and SIGINT is all
we really need. *)
Deferred.upon stop (fun () -> Core.Signal.Expert.set Signal.int `Default);
let%bind () = detach attachment in
return pid
;;
Expand All @@ -497,6 +501,7 @@ module Make_commands (Backend : Backend_intf.S) = struct
Async_unix.Signal.handle ~stop [ Signal.int ] ~f:(fun (_ : Signal.t) ->
Core.eprintf "[ Got signal, detaching... ]\n%!";
Ivar.fill_if_empty done_ivar ());
Deferred.upon stop (fun () -> Core.Signal.Expert.set Signal.int `Default);
Core.eprintf "[ Attached. Press Ctrl-C to stop recording. ]\n%!";
let%bind () = stop in
detach attachment
Expand Down

0 comments on commit 492afe4

Please sign in to comment.