title: Suspending Erlang Processes
body: <p>I am tracing an Erlang process, say, <code>P</code> by invoking the BIF <code>erlang:trace(Pid_P, true, [set_on_spawn, procs, send, 'receive'])</code> from some process. As per the Erlang docs, the latter process becomes the tracer for <code>P</code>, which I shall call <code>Trc_Q</code>.</p>
  
  <p>Suppose now, that process <code>P</code> spawns a new process <code>Q</code>. Since the flag <code>set_on_spawn</code> was specified in the call to <code>erlang:trace/3</code> above, <code>Q</code> will automatically be traced by <code>Trc_P</code> as well.</p>
  
  <hr>
  
  <p>I want to spawn a <strong>new</strong> tracer, <code>Trc_Q</code>, and transfer the ownership of tracing <code>Q</code> to it, so that the resulting configuration will be that of process <code>P</code> being traced by tracer <code>Trc_P</code>, <code>Q</code> by <code>Trc_Q</code>.</p>
  
  <p>However, Erlang permits <strong>at most</strong> one tracer per process, so I cannot achieve said configuration by invoking <code>erlang:trace(Pid_Q, true, ..)</code> from <code>Trc_Q</code>. The only way possible is to do it in two steps:</p>
  
  <ol>
  <li>Tracer <code>Trc_Q</code> calls <code>erlang:trace(Pid_Q, false, ..)</code> to stop <code>Trc_P</code> from tracing <code>Q</code>;</li>
  <li><code>Trc_Q</code> calls <code>erlang:trace(Pid_Q, true, ..)</code> again to start tracing <code>Q</code>.</li>
  </ol>
  
  <p>In the time span between steps <strong>1.</strong> and <strong>2.</strong> above, it might be possible that trace events by process <code>Q</code> are <strong>lost</strong> because at that moment, there is no tracer attached. One way of mitigating this is to perform the following:</p>
  
  <ol>
  <li>Suspend process <code>Q</code> by calling <code>erlang:suspend_process(Pid_Q)</code> from <code>Trc_Q</code> (note that as per Erlang docs, <code>Trc_Q</code> remains blocked until <code>Q</code> is eventually suspended by the VM);</li>
  <li><code>Trc_Q</code> calls <code>erlang:trace(Pid_Q, false, ..)</code> to stop <code>Trc_P</code> from tracing <code>Q</code>;</li>
  <li><code>Trc_Q</code> calls <code>erlang:trace(Pid_Q, true, ..)</code> again to start tracing <code>Q</code>;</li>
  <li>Finally, <code>Trc_Q</code> calls <code>erlang:resume_process(Pid_Q)</code> so that <code>Q</code> can continue executing.</li>
  </ol>
  
  <p>From what I was able to find out, while <code>Q</code> is suspended, messages sent to it are queued, and when resumed, <code>Trc_Q</code> receives the <code>{trace, Pid_Q, receive, Msg}</code> trace events accordingly without any loss. </p>
  
  <p>I have one constraint which led me to look at suspend/resume process: I cannot modify the code of <code>P</code> or <code>Q</code>, so inserting <code>receive</code> expressions to block said processes is out of the question.</p>
  
  <p>However, I am hesitant to use suspend/resume, since the Erlang docs explicitly say that these are to be used for <em>debugging purposes only</em>. Any idea as to why this is the case?</p>