<div dir="ltr">As a follow up on Rickards answer I think it would be interesting if you can explain why you want different tracers per process?<div>If we know what problem you want to solve we can most probably come with better suggestions.</div><div><br></div><div>I also recommend that you use tracing via the dbg module which is intended to be a more user friendly API towards tracing. The trace BIFs might give some more detailed control but dbg has support for most use cases and makes it easier to do the right thing, at least that is the intention.</div><div><br></div><div>Also worth mentioning is that the tracing mechanisms are really not intended to use to achieve a certain functionality which is part of the application, they are intended to be used temporarily for debugging/profiling purposes. Since there is only one tracer at the time the use of tracing as part of the "ordinary" implementation of an application there will be conflicts as soon as any tracing or profiling is needed and probably the intended functionality of the application will then be broken.</div><div><br></div><div>/Kenneth, Erlang/OTP Ericsson</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Oct 1, 2019 at 10:07 PM Rickard Green <<a href="mailto:rickard@erlang.org">rickard@erlang.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br><br>On Mon, Sep 30, 2019 at 1:57 PM Duncan Paul Attard <<a href="mailto:duncan.attard.01@um.edu.mt" target="_blank">duncan.attard.01@um.edu.mt</a>> wrote:<br>><br>> I am tracing an Erlang process, say, `P` by invoking the BIF `erlang:trace(Pid_P, true, [set_on_spawn, procs, send, 'receive'])` from some process. As per the Erlang docs, the latter process becomes the tracer for `P`, which I shall call `Trc_Q`.<br>><br>> Suppose now, that process `P` spawns a new process `Q`. Since the flag `set_on_spawn` was specified in the call to `erlang:trace/3` above, `Q` will automatically be traced by `Trc_P` as well.<br>><br>> ---<br>><br>> I want to spawn a **new** tracer, `Trc_Q`, and transfer the ownership of tracing `Q` to it, so that the resulting configuration will be that of process `P` being traced by tracer `Trc_P`, `Q` by `Trc_Q`.<br>><br><br></div>Unfortunately I do not have any ideas on how to accomplish this.<br><div><br>> However, Erlang permits **at most** one tracer per process, so I cannot achieve said configuration by invoking `erlang:trace(Pid_Q, true, ..)` from `Trc_Q`. The only way possible is to do it in two steps:<br>><br>> 1. Tracer `Trc_Q` calls `erlang:trace(Pid_Q, false, ..)` to stop `Trc_P` from tracing `Q`;<br>> 2. `Trc_Q` calls `erlang:trace(Pid_Q, true, ..)` again to start tracing `Q`.<br>><br>> In the time span between steps **1.** and **2.** above, it might be possible that trace events by process `Q` are **lost** because at that moment, there is no tracer attached. One way of mitigating this is to perform the following:<br>><br>> 1. Suspend process `Q` by calling `erlang:suspend_process(Pid_Q)` from `Trc_Q` (note that as per Erlang docs, `Trc_Q` remains blocked until `Q` is eventually suspended by the VM);<br>> 2. `Trc_Q` calls `erlang:trace(Pid_Q, false, ..)` to stop `Trc_P` from tracing `Q`;<br>> 3. `Trc_Q` calls `erlang:trace(Pid_Q, true, ..)` again to start tracing `Q`;<br>> 4. Finally, `Trc_Q` calls `erlang:resume_process(Pid_Q)` so that `Q` can continue executing.<br>><br>> From what I was able to find out, while `Q` is suspended, messages sent to it are queued, and when resumed, `Trc_Q` receives the `{trace, Pid_Q, receive, Msg}` trace events accordingly without any loss.<br>><br><br>This is not a feature, it is a bug (introduced in erts 10.0, OTP 21.0) that will be fixed. The trace message should have been delivered even though the receiver was suspended.<br><br>You cannot even rely on this behavior while this bug is present. If you (or any process in the system) send the suspended process a non-message signal (monitor, demonitor, link, unlink, exit, process_info, ...), the bug will be bypassed and the trace message will be delivered.<br><br>> However, I am hesitant to use suspend/resume, since the Erlang docs explicitly say that these are to be used for *debugging purposes only*.<br><br>Mission accomplished! :-)<br><br>> Any idea as to why this is the case?<br>><br><br>The language was designed with other communication primitives intended for use. Suspend/Resume was explicitly introduced for debugging purposes only, and not for usage by ordinary Erlang programs. They will most likely not disappear, but debug functionality in general are not treated as carefully by us at OTP as other ordinary functionality with regards to compatibility, etc. We for example removed the automatic deadlock prevention in suspend_process() that existed prior to erts 10.0 due to performance reasons.<br><br>Regards,<br>Rickard<br>--<br>Rickard Green, Erlang/OTP, Ericsson AB</div></div>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div>