12345678910111213141516171819202122232425262728293031open!Coreexternalptrace_traceme:unit->bool="magic_ptrace_traceme"(* Same as [Caml.exit] but does not run at_exit handlers *)externalsys_exit:int->'a="caml_sys_exit"letfork_exec_stopped~prog~argv()=letpr_set_pdeathsig=Or_error.ok_exnLinux_ext.pr_set_pdeathsiginmatchCore_unix.fork()with|`In_the_child->(* Don't outlive the magic-trace parent process. *)pr_set_pdeathsigSignal.kill;(* This is how we ensure the process is started in a stopped state: we mark ourselves
as traced, so that we receive a `SIGTRAP` after `exec*` completes. *)ifnot(ptrace_traceme())thensys_exit126;never_returns(tryCore_unix.exec~prog~argv()with|_->sys_exit127)|`In_the_parentpid->(matchCore_unix.wait_untraced(`Pidpid)with|_,Error(`Stop_)->pid|_,result->raise_s[%message"expected child to stop but it did not"(pid:Pid.t)(result:(unit,Core_unix.Exit_or_signal_or_stop.error)Result.t)]);;externalresume:Pid.t->unit="magic_ptrace_detach"